# # Gramps - a GTK+/GNOME based genealogy program # # Copyright (C) 2000-2003 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 # # $Id$ #------------------------------------------------------------------------- # # Standard Python Modules # #------------------------------------------------------------------------- import os import tempfile import string import zipfile import time from math import pi, cos, sin, fabs #------------------------------------------------------------------------- # # Gramps modules # #------------------------------------------------------------------------- import Errors import BaseDoc import const import Plugins import ImgManip import FontScale import grampslib #------------------------------------------------------------------------- # # internationalization # #------------------------------------------------------------------------- from gettext import gettext as _ _apptype = 'application/vnd.sun.xml.writer' #------------------------------------------------------------------------- # # OpenOfficeDoc # #------------------------------------------------------------------------- class OpenOfficeDoc(BaseDoc.BaseDoc): def __init__(self,styles,type,template,orientation=BaseDoc.PAPER_PORTRAIT): BaseDoc.BaseDoc.__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 self.new_cell = 0 self.page = 0 self.first_page = 1 def set_mode(self, mode): self.mode = mode def open(self,filename): 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 self.filename = os.path.normpath(os.path.abspath(filename)) try: self.content_xml = tempfile.mktemp() self.f = open(self.content_xml,"wb") except IOError,msg: raise Errors.ReportError(_("Could not create %s") % self.content_xml, msg) except: raise Errors.ReportError(_("Could not create %s") % self.content_xml) def init(self): self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('') self.f.write('') self.f.write('\n') self.f.write('') self.f.write('') self.f.write('\n') for style_name in self.draw_styles.keys(): style = self.draw_styles[style_name] self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') for style_name in self.style_list.keys(): style = self.style_list[style_name] self.f.write('\n' % style_name) self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write(' 0: self.f.write('fo:keep-with-next="true" ') align = style.get_alignment() if align == BaseDoc.PARA_ALIGN_LEFT: self.f.write('fo:text-align="start" ') elif align == BaseDoc.PARA_ALIGN_RIGHT: self.f.write('fo:text-align="end" ') elif align == BaseDoc.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() == BaseDoc.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('\n') self.f.write('\n') self.f.write('' % font.get_size()) self.f.write('\n') for style_name in self.table_styles.keys(): style = self.table_styles[style_name] self.f.write('\n') table_width = float(self.get_usable_width()) table_width_str = "%.4f" % table_width self.f.write('\n') self.f.write('\n') for col in range(0,style.get_columns()): self.f.write('') width = table_width * float(style.get_column_width(col)/100.0) width_str = "%.4f" % width self.f.write('' % width_str) self.f.write('\n') for cell in self.cell_styles.keys(): cell_style = self.cell_styles[cell] self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') #Begin photo style self.f.write('') self.f.write('') self.f.write('\n') self.f.write('') self.f.write('') self.f.write('\n') self.f.write('') self.f.write('') self.f.write('\n') self.f.write('') self.f.write('') self.f.write('\n') #end of Photo style edits self.f.write('\n') self.f.write('\n') def close(self): self.f.write('\n') self.f.write('\n') self.f.close() self._write_styles_file() self._write_manifest() self._write_meta_file() self._write_zip() if self.print_req: app = grampslib.default_application_command(_apptype) os.environ["FILE"] = self.filename os.system ('%s "$FILE" &' % app) def add_media_object(self,name,pos,x_cm,y_cm): # try to open the image. If the open fails, it probably wasn't # a valid image (could be a PDF, or a non-image) try: image = ImgManip.ImgManip(name) (x,y) = image.size() ratio = float(x_cm)*float(y)/(float(y_cm)*float(x)) except: return if ratio < 1: act_width = x_cm act_height = y_cm*ratio else: act_height = y_cm act_width = x_cm/ratio media_list_item = (name,act_width,act_height) if not media_list_item in self.media_list: self.media_list.append(media_list_item) base = os.path.basename(name) tag = string.replace(base,'.','_') if self.new_cell: self.f.write('') if pos == "left": self.f.write('\n') if self.new_cell: self.f.write('\n') def start_table(self,name,style_name): self.f.write('\n' % style_name) table = self.table_styles[style_name] for col in range(0,table.get_columns()): self.f.write('\n') def end_table(self): self.f.write('\n') def start_row(self): self.f.write('\n') def end_row(self): self.f.write('\n') def start_cell(self,style_name,span=1): self.span = span self.f.write(' 1: self.f.write(' table:number-columns-spanned="%s">\n' % span) else: self.f.write('>\n') self.new_cell = 1 def end_cell(self): self.f.write('\n') for col in range(1,self.span): self.f.write('\n') self.new_cell = 0 def start_bold(self): self.f.write('') def end_bold(self): self.f.write('') def _write_zip(self): file = zipfile.ZipFile(self.filename,"w",zipfile.ZIP_DEFLATED) file.write(self.manifest_xml,str("META-INF/manifest.xml")) file.write(self.content_xml,str("content.xml")) file.write(self.meta_xml,str("meta.xml")) file.write(self.styles_xml,str("styles.xml")) for image in self.media_list: base = os.path.basename(image[0]) file.write(image[0], str("Pictures/%s" % base)) file.close() os.unlink(self.manifest_xml) os.unlink(self.content_xml) os.unlink(self.meta_xml) os.unlink(self.styles_xml) def _write_styles_file(self): self.styles_xml = tempfile.mktemp() try: self.f = open(self.styles_xml,"wb") except IOError,msg: errmsg = "%s\n%s" % (_("Could not create %s") % self.styles_xml, msg) raise Errors.ReportError(errmsg) except: pass raise Errors.ReportError(_("Could not create %s") % self.styles_xml) self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') for key in self.style_list.keys(): style = self.style_list[key] self.f.write('\n') self.f.write(' 0: self.f.write('fo:keep-with-next="true" ') align = style.get_alignment() if align == BaseDoc.PARA_ALIGN_LEFT: self.f.write('fo:text-align="start" ') elif align == BaseDoc.PARA_ALIGN_RIGHT: self.f.write('fo:text-align="end" ') elif align == BaseDoc.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() == BaseDoc.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('\n') # Current no leading number format for headers self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.close() def page_break(self): self.new_page = 1 def start_page(self): self.f.write('\n') def end_page(self): self.f.write('\n') 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('' % name) else: self.f.write('\n') if leader != None: self.f.write(leader) self.f.write('\n') self.new_cell = 0 def end_paragraph(self): if self.level == 0: self.f.write('\n') else: self.f.write('\n') self.new_cell = 1 def write_note(self,text,format,style_name): if format == 1: text = text.replace('&','&') # Must be first text = text.replace('<','<') text = text.replace('>','>') # Replace multiple spaces: have to go from the largest number down for n in range(text.count(' '),1,-1): text = text.replace(' '*n, ' ' % (n-1) ) text = text.replace('\n','') text = text.replace('\t','') text = text.replace('<super>','') text = text.replace('</super>','') self.start_paragraph(style_name) self.f.write('') self.f.write(text) self.f.write('') self.end_paragraph() elif format == 0: for line in text.split('\n\n'): self.start_paragraph(style_name) line = line.replace('\n',' ') line = string.join(string.split(line)) self.write_text(line) self.end_paragraph() def write_text(self,text): text = text.replace('&','&') # Must be first text = text.replace('<','<') text = text.replace('>','>') text = text.replace('\n','') text = text.replace('<super>','') text = text.replace('</super>','') self.f.write(text) def _write_manifest(self): self.manifest_xml = tempfile.mktemp() try: self.f = open(self.manifest_xml,"wb") except IOError,msg: errmsg = "%s\n%s" % (_("Could not create %s") % self.manifest_xml, msg) raise Errors.ReportError(errmsg) except: pass raise Errors.ReportError(_("Could not create %s") % self.manifest_xml) self.f.write('\n') self.f.write('') self.f.write('') for image in self.media_list: i = image[0] base = os.path.basename(i) self.f.write('') self.f.write('') self.f.write('') self.f.write('') self.f.write('') self.f.write('\n') self.f.close() def _write_meta_file(self): name = self.name self.meta_xml = tempfile.mktemp() try: self.f = open(self.meta_xml,"wb") except IOError,msg: errmsg = "%s\n%s" % (_("Could not create %s") % self.meta_xml, msg) raise Errors.ReportError(errmsg) except: pass raise Errors.ReportError(_("Could not create %s") % self.meta_xml) self.f.write('\n') self.f.write('\n'); self.f.write('\n') self.f.write('') self.f.write(const.progName + ' ' + const.version) self.f.write('\n') self.f.write('') self.f.write(name) self.f.write('\n') self.f.write('') self.f.write(self.time) self.f.write('\n') self.f.write('') self.f.write(name) self.f.write('\n') self.f.write('') self.f.write(self.time) self.f.write('\n') self.f.write('0-00-00T00:00:00\n') self.f.write('en-US\n') self.f.write('1\n') self.f.write('PT0S\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.write('\n') self.f.close() def rotate_text(self,style,text,x,y,angle): stype = self.draw_styles[style] pname = stype.get_paragraph_style() p = self.style_list[pname] font = p.get_font() size = font.get_size() height = size*(len(text)) oneline = (size/72.0)*2.54 width = 0 for line in text: width = max(width,FontScale.string_width(font,line)) wcm = (width/72.0)*2.54 hcm = (height/72.0)*2.54 rangle = -((pi/180.0) * angle) self.f.write('') self.f.write('' % pname) self.f.write('\n' % pname) self.write_text(string.join(text,'\n')) self.f.write('\n\n\n') def draw_path(self,style,path): minx = 9e12 miny = 9e12 maxx = 0 maxy = 0 for point in path: minx = min(point[0],minx) miny = min(point[1],miny) maxx = max(point[0],maxx) maxy = max(point[1],maxy) self.f.write('\n') def draw_line(self,style,x1,y1,x2,y2): self.f.write('\n') def draw_text(self,style,text,x,y): box_style = self.draw_styles[style] para_name = box_style.get_paragraph_style() pstyle = self.style_list[para_name] font = pstyle.get_font() if box_style.get_width(): sw = box_style.get_width() else: sw = FontScale.string_width(font,text)*1.3 self.f.write('' % float(y)) self.f.write('' % para_name) self.f.write('' % para_name) self.f.write(text) self.f.write('') self.f.write('\n') def draw_bar(self,style,x,y,x2,y2): box_style = self.draw_styles[style] self.f.write('' % float(y)) self.f.write('\n') def draw_box(self,style,text,x,y): box_style = self.draw_styles[style] para_name = box_style.get_paragraph_style() shadow_width = box_style.get_shadow_space() if box_style.get_shadow(): self.f.write('\n' % (float(y)+shadow_width)) self.f.write('\n') self.f.write('\n' % float(y)) if text != "": self.f.write('' % para_name) self.f.write('' % para_name) text = string.replace(text,'\t','') text = string.replace(text,'\n','') self.f.write(text) self.f.write('') self.f.write('\n') self.f.write('\n') def center_text(self,style,text,x,y): box_style = self.draw_styles[style] para_name = box_style.get_paragraph_style() pstyle = self.style_list[para_name] font = pstyle.get_font() size = 1.1*(FontScale.string_width(font,text)/72.0) * 2.54 self.f.write('\n' % float(y)) if text != "": self.f.write('' % para_name) self.f.write(text) self.f.write('\n') self.f.write('\n') #-------------------------------------------------------------------------- # # Register plugins # #-------------------------------------------------------------------------- print_label = None try: import Utils prog = grampslib.default_application_command(_apptype) if Utils.search_for(prog): print_label = _("Open in OpenOffice.org") except: pass Plugins.register_text_doc( _("OpenOffice.org Writer"), OpenOfficeDoc, 1, 1, 1, ".sxw", print_label) Plugins.register_book_doc( _("OpenOffice.org Writer"), OpenOfficeDoc, 1, 1, 1, ".sxw") Plugins.register_draw_doc( _("OpenOffice.org Draw"), OpenOfficeDoc, 1, 1, ".sxd", print_label);