Moved base report designer in extra_addons
bzr revid: fp@tinyerp.com-a52fb2798427107a6ca1e5569fc1371d4af3f42e
This commit is contained in:
parent
022ba7101f
commit
4c408bfb25
|
@ -96,15 +96,16 @@ class account_move_line(osv.osv):
|
|||
bank_type = payment_mode_obj.suitable_bank_types(cr, uid, payment_type,
|
||||
context=context)
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
line2bank[line.id] = False
|
||||
if line.invoice and line.invoice.partner_bank:
|
||||
line2bank[line.id] = line.invoice.partner_bank.id
|
||||
elif line.partner:
|
||||
for bank in line.partner.bank_ids:
|
||||
elif line.partner_id:
|
||||
for bank in line.partner_id.bank_ids:
|
||||
if bank.state in bank_type:
|
||||
line2bank[line.id] = bank.id
|
||||
break
|
||||
if line.id not in line2bank and line.partner.bank_ids:
|
||||
line2bank[line.id] = line.partner.bank_ids[0].id
|
||||
if line.id not in line2bank and line.partner_id.bank_ids:
|
||||
line2bank[line.id] = line.partner_id.bank_ids[0].id
|
||||
return line2bank
|
||||
|
||||
_columns = {
|
||||
|
|
|
@ -95,11 +95,11 @@ class payment_order(osv.osv):
|
|||
|
||||
_columns = {
|
||||
'date_planned': fields.date('Scheduled date if fixed'),
|
||||
'reference': fields.char('Reference',size=128),
|
||||
'mode': fields.many2one('payment.mode','Payment mode', select=True),
|
||||
'reference': fields.char('Reference',size=128,required=1),
|
||||
'mode': fields.many2one('payment.mode','Payment mode', select=True, required=1),
|
||||
'state': fields.selection([
|
||||
('draft', 'Draft'),
|
||||
('open','Open'),
|
||||
('open','Confirmed'),
|
||||
('cancel','Cancelled'),
|
||||
('done','Done')], 'State', select=True),
|
||||
'line_ids': fields.one2many('payment.line','order_id','Payment lines'),
|
||||
|
@ -120,8 +120,7 @@ class payment_order(osv.osv):
|
|||
'state': lambda *a: 'draft',
|
||||
'date_prefered': lambda *a: 'due',
|
||||
'date_created': lambda *a: time.strftime('%Y-%m-%d'),
|
||||
'reference': lambda self,cr,uid,context: self.pool.get('ir.sequence'
|
||||
).get(cr, uid, 'payment.order'),
|
||||
'reference': lambda self,cr,uid,context: self.pool.get('ir.sequence').get(cr, uid, 'payment.order'),
|
||||
}
|
||||
|
||||
def set_to_draft(self, cr, uid, ids, *args):
|
||||
|
@ -167,6 +166,18 @@ class payment_line(osv.osv):
|
|||
"due_date": "date_maturity",
|
||||
"reference": "ref"}.get(orig, orig)
|
||||
|
||||
def info_owner(self, cr, uid, ids, name, args, context=None):
|
||||
if not ids: return {}
|
||||
result = {}
|
||||
for id in ids:
|
||||
result[id] = """Tiny SPRL
|
||||
126-12021213-07 (Fortis)
|
||||
Chaussee de Namlur 40
|
||||
1367 Grand Rosiere
|
||||
Belgique"""
|
||||
return result
|
||||
|
||||
info_partner = info_owner
|
||||
def select_by_name(self, cr, uid, ids, name, args, context=None):
|
||||
if not ids: return {}
|
||||
|
||||
|
@ -279,7 +290,9 @@ class payment_line(osv.osv):
|
|||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, readonly=True),
|
||||
'name': fields.char('Your Reference', size=64, required=True),
|
||||
'communication': fields.char('Communication', size=64),
|
||||
'communication2': fields.char('Communication 2', size=64),
|
||||
'move_line_id': fields.many2one('account.move.line','Entry line',
|
||||
required=True),
|
||||
'amount_currency': fields.float('Amount', digits=(16,2),
|
||||
|
@ -292,8 +305,7 @@ class payment_line(osv.osv):
|
|||
'bank_id': fields.many2one('res.partner.bank', 'Bank account'),
|
||||
'order_id': fields.many2one('payment.order', 'Order', required=True,
|
||||
ondelete='cascade', select=True),
|
||||
'partner_id': fields.function(select_by_name, string="Partner",
|
||||
method=True, type='many2one', obj='res.partner'),
|
||||
'partner_id': fields.many2one('res.partner', string="Partner"),
|
||||
'amount': fields.function(_amount, string='Amount',
|
||||
method=True, type='float',
|
||||
help='Payment amount in the company currency'),
|
||||
|
@ -305,14 +317,19 @@ class payment_line(osv.osv):
|
|||
method=True, type='date'),
|
||||
'reference': fields.function(select_by_name, string="Ref", method=True,
|
||||
type='char'),
|
||||
'info_owner': fields.function(info_owner, string="Owner Account", method=True, type="text"),
|
||||
'info_partner': fields.function(info_partner, string="Owner Account", method=True, type="text"),
|
||||
'partner_payable': fields.function(partner_payable,
|
||||
string="Partner payable", method=True, type='float'),
|
||||
'value_date': fields.function(_value_date, string='Value Date',
|
||||
method=True, type='date'),
|
||||
'date': fields.date('Memo Date'),
|
||||
'state': fields.selection([('normal','Normal'), ('structured','Structured')], 'State', required=True)
|
||||
}
|
||||
_defaults = {
|
||||
'name': lambda obj, cursor, user, context: obj.pool.get('ir.sequence'
|
||||
).get(cursor, user, 'payment.line'),
|
||||
'state': lambda *args: 'normal'
|
||||
}
|
||||
_sql_constraints = [
|
||||
('name_uniq', 'UNIQUE(name)', 'The payment line name must be unique!'),
|
||||
|
|
|
@ -143,22 +143,47 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Payment Line">
|
||||
<field name="move_line_id"
|
||||
select="1"
|
||||
on_change="onchange_move_line(move_line_id,parent.mode.type.code)"
|
||||
domain="[('reconcile_id','=', False), ('credit', '>',0),('amount_to_pay','>',0)] "/>
|
||||
<newline/>
|
||||
<field name="amount_currency" select="1"/>
|
||||
<field name="to_pay_currency"/>
|
||||
<field name="currency"/>
|
||||
<field name="bank_id" domain="[('partner_id','=',partner_id)]"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="reference"/>
|
||||
<field name="due_date"/>
|
||||
<field name="amount" select="2" />
|
||||
<field name="to_pay"/>
|
||||
<field name="partner_payable"/>
|
||||
<field name="date_created"/>
|
||||
<notebook>
|
||||
<page string="Payment">
|
||||
<field name="move_line_id"
|
||||
select="1"
|
||||
on_change="onchange_move_line(move_line_id,parent.mode.type.code)"
|
||||
domain="[('reconcile_id','=', False), ('credit', '>',0),('amount_to_pay','>',0)] "/>
|
||||
<separator string="Transaction Information" colspan="4"/>
|
||||
<field name="date"/>
|
||||
<field name="amount" select="1"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="bank_id" domain="[('partner_id','=',partner_id)]"/>
|
||||
<separator string="Owner Account" colspan="2"/>
|
||||
<separator string="Desitination Account" colspan="2"/>
|
||||
<field name="info_owner" colspan="2" nolabel="1"/>
|
||||
<field name="info_partner" colspan="2" nolabel="1"/>
|
||||
|
||||
<field name="communication" colspan="4"/>
|
||||
<field name="communication2" colspan="4"/>
|
||||
<field name="name"/> <field name="state"/>
|
||||
</page><page string="Information">
|
||||
|
||||
<separator string="General Information" colspan="2"/>
|
||||
<separator string="Entry Information" colspan="2"/>
|
||||
<group colspan="2" col="2">
|
||||
<field name="amount_currency" select="1"/>
|
||||
<field name="currency"/>
|
||||
<newline/>
|
||||
<field name="partner_payable"/>
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<field name="date_created"/>
|
||||
<field name="due_date"/>
|
||||
|
||||
<field name="to_pay_currency"/>
|
||||
<field name="to_pay"/>
|
||||
|
||||
</group>
|
||||
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -170,21 +195,19 @@
|
|||
<field name="arch" type="xml">
|
||||
<tree string="Payment Line" editable="bottom"
|
||||
colors="red:to_pay_currency<amount_currency">
|
||||
<field name="partner_id"/>
|
||||
|
||||
<field name="move_line_id" select="1"
|
||||
on_change="onchange_move_line(move_line_id,parent.mode)"
|
||||
domain="[('reconcile_id', '=', False), ('credit', '>', 0), ('amount_to_pay', '>', 0)]"/>
|
||||
domain="[('partner_id','=',partner_id),('reconcile_id', '=', False), ('credit', '>', 0), ('amount_to_pay', '>', 0)]"/>
|
||||
<field name="bank_id" domain="[('partner_id', '=', partner_id)]"/>
|
||||
<field name="amount_currency"/>
|
||||
<field name="to_pay_currency"/>
|
||||
<field name="currency"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="reference"/>
|
||||
<field name="due_date"/>
|
||||
<field name="amount" sum="Amount Total"/>
|
||||
<field name="to_pay"/>
|
||||
<field name="partner_payable"/>
|
||||
<field name="date_created"/>
|
||||
<field name="name"/>
|
||||
|
||||
<field name="amount_currency" sum="Total Amount"/>
|
||||
<field name="communication"/>
|
||||
<field name="state"/>
|
||||
<field name="date"/>
|
||||
<field name="to_pay_currency" invisible="1"/>
|
||||
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -92,6 +92,8 @@ def create_payment(self, cr, uid, data, context):
|
|||
'amount_currency': line.amount_to_pay,
|
||||
'bank_id': line2bank.get(line.id),
|
||||
'order_id': payment.id,
|
||||
'partner_id': line.partner_id and line.partner_id.id or False,
|
||||
'communication': line.ref or '/'
|
||||
}, context=context)
|
||||
return {}
|
||||
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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 base_report_designer
|
||||
import wizard
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
"name" : "Report designer interface module",
|
||||
"description" : """
|
||||
This module adds wizards to import/export documents to be edited in
|
||||
OpenOffice.
|
||||
""",
|
||||
"version" : "0.1",
|
||||
"depends" : ["base"],
|
||||
"author" : "Tiny",
|
||||
"website" : "http://tinyerp.com",
|
||||
"category" : "Generic Modules/Base",
|
||||
"init_xml" : [ ],
|
||||
"demo_xml" : [ ],
|
||||
"update_xml" : [ "base_report_designer_wizard.xml" ],
|
||||
"active": False,
|
||||
"installable": True
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004-2007 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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 osv import fields,osv
|
||||
from wizard.tiny_sxw2rml import sxw2rml
|
||||
from StringIO import StringIO
|
||||
from report import interface
|
||||
import base64
|
||||
import pooler
|
||||
import tools
|
||||
|
||||
class report_xml(osv.osv):
|
||||
_inherit = 'ir.actions.report.xml'
|
||||
|
||||
def sxwtorml(self,cr, uid, file_sxw):
|
||||
'''
|
||||
The use of this function is to get rml file from sxw file.
|
||||
'''
|
||||
sxwval = StringIO(base64.decodestring(file_sxw))
|
||||
fp = tools.file_open('normalized_oo2rml.xsl',
|
||||
subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
|
||||
return {'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read()))}
|
||||
|
||||
def upload_report(self, cr, uid, report_id, file_sxw, context):
|
||||
'''
|
||||
Untested function
|
||||
'''
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
sxwval = StringIO(base64.decodestring(file_sxw))
|
||||
fp = tools.file_open('normalized_oo2rml.xsl',
|
||||
subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
|
||||
report = pool.get('ir.actions.report.xml').write(cr, uid, [report_id], {
|
||||
'report_sxw_content': base64.decodestring(file_sxw),
|
||||
'report_rml_content': str(sxw2rml(sxwval, xsl=fp.read()))
|
||||
})
|
||||
cr.commit()
|
||||
db = pooler.get_db_only(cr.dbname)
|
||||
interface.register_all(db)
|
||||
return True
|
||||
def report_get(self, cr, uid, report_id, context={}):
|
||||
report = self.browse(cr, uid, report_id, context)
|
||||
return {
|
||||
'report_sxw_content': report.report_sxw_content and base64.encodestring(report.report_sxw_content) or False,
|
||||
'report_rml_content': report.report_rml_content and base64.encodestring(report.report_rml_content) or False
|
||||
}
|
||||
report_xml()
|
|
@ -1,22 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
<wizard
|
||||
string="Modify an existing report"
|
||||
model="ir.actions.report.xml"
|
||||
name="base_report_designer.modify"
|
||||
id="wizard_report_designer_modify"/>
|
||||
|
||||
<menuitem
|
||||
name="Administration/Custom/Report Designer"
|
||||
action="wizard_report_designer_modify"
|
||||
type="wizard"
|
||||
id="menu_wizard_report_designer_modify"/>
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</terp>
|
||||
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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 base_report_designer_modify
|
|
@ -1,230 +0,0 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-2007 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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 time
|
||||
import wizard
|
||||
import osv
|
||||
import pooler
|
||||
import urllib
|
||||
import base64
|
||||
import tools
|
||||
|
||||
intro_form = '''<?xml version="1.0"?>
|
||||
<form string="Report designer">
|
||||
<separator string="Report designer introduction" colspan="4"/>
|
||||
<field name="text" colspan="4" nolabel="1"/>
|
||||
</form>'''
|
||||
|
||||
intro_fields = {
|
||||
'text': {
|
||||
'string': 'Introduction',
|
||||
'type': 'text',
|
||||
'readonly': True,
|
||||
'default': lambda *args: """This system must be used with the Tiny OpenOffice plugin. If you
|
||||
did not installed yet, you can find this package on:
|
||||
http://tinyerp.com
|
||||
|
||||
This wizard will provide you the .SXW report that you can modify
|
||||
in OpenOffice. After having modified it, you will be able to reupload
|
||||
it to the Tiny ERP server.
|
||||
"""},
|
||||
'operation': {
|
||||
'string': 'Operation',
|
||||
'type': 'selection',
|
||||
'selection': [
|
||||
('create','Create a new report'),
|
||||
('modify','Modify an existing report')
|
||||
],
|
||||
'size': 32,
|
||||
'required': True,
|
||||
'default': lambda *args: 'create',
|
||||
},
|
||||
}
|
||||
|
||||
get_form = '''<?xml version="1.0"?>
|
||||
<form string="Get a report">
|
||||
<separator string="Select your report" colspan="4"/>
|
||||
<field name="report_id"/>
|
||||
</form>'''
|
||||
|
||||
get_fields = {
|
||||
'report_id': {
|
||||
'string': 'Report',
|
||||
'type': 'many2one',
|
||||
'relation': 'ir.actions.report.xml',
|
||||
'required': True,
|
||||
'domain': [('report_sxw_content','<>',False)],
|
||||
},
|
||||
}
|
||||
|
||||
get_form_result = '''<?xml version="1.0"?>
|
||||
<form string="Get a report">
|
||||
<separator string="The .SXW report" colspan="4"/>
|
||||
<field name="report_id"/>
|
||||
<newline/>
|
||||
<field name="file_sxw"/>
|
||||
<newline/>
|
||||
<label colspan="4" string="This is the template of your requested report.\nSave it as a .SXW file and open it with OpenOffice.\nDon't forget to install the Tiny OpenOffice package to modify it.\nOnce it is modified, re-upload it in Tiny ERP using this wizard." align="0.0"/>
|
||||
</form>'''
|
||||
|
||||
get_form_fields = {
|
||||
'report_id': {
|
||||
'string': 'Report',
|
||||
'type': 'many2one',
|
||||
'relation': 'ir.actions.report.xml',
|
||||
'readonly': True,
|
||||
},
|
||||
'file_sxw': {
|
||||
'string': 'Your .SXW file',
|
||||
'type': 'binary',
|
||||
'readonly': True,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
send_form_result_arch = '''<?xml version="1.0"?>
|
||||
<form string="Report modified">
|
||||
<separator string="Report modified" colspan="4"/>
|
||||
<label string="Your report has been modified."/>
|
||||
</form>'''
|
||||
|
||||
send_form_result_fields = {
|
||||
}
|
||||
|
||||
|
||||
send_form_arch = '''<?xml version="1.0"?>
|
||||
<form string="Get a report">
|
||||
<separator string="Upload your modified report" colspan="4"/>
|
||||
<field name="report_id"/>
|
||||
<newline/>
|
||||
<field name="file_sxw"/>
|
||||
</form>'''
|
||||
|
||||
send_form_fields = {
|
||||
'report_id': {
|
||||
'string': 'Report',
|
||||
'type': 'many2one',
|
||||
'relation': 'ir.actions.report.xml',
|
||||
'required': True,
|
||||
'domain': [('report_sxw_content','<>',False)]
|
||||
},
|
||||
'file_sxw': {
|
||||
'string': 'Your .SXW file',
|
||||
'type': 'binary',
|
||||
'required': True
|
||||
}
|
||||
}
|
||||
|
||||
def _get_default(obj, cursor, user, data, context):
|
||||
return {'report_id': data['id']}
|
||||
|
||||
|
||||
class base_report_designer_modify(wizard.interface):
|
||||
def _upload_report_clear(self, cr, uid, data, context):
|
||||
return {'file_sxw': False}
|
||||
|
||||
def _upload_report(self, cr, uid, data, context):
|
||||
import tiny_sxw2rml
|
||||
import StringIO
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
sxwval = StringIO.StringIO(base64.decodestring(data['form']['file_sxw']))
|
||||
fp = tools.file_open('normalized_oo2rml.xsl',subdir='addons/base_report_designer/wizard/tiny_sxw2rml')
|
||||
report = pool.get('ir.actions.report.xml').write(cr, uid, [data['form']['report_id']], {
|
||||
'report_sxw_content': base64.decodestring(data['form']['file_sxw']),
|
||||
'report_rml_content': str(tiny_sxw2rml.sxw2rml(sxwval, xsl=fp.read()))
|
||||
})
|
||||
return {}
|
||||
|
||||
def _get_report(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
report = pool.get('ir.actions.report.xml').browse(cr, uid, data['form']['report_id'], context)
|
||||
return {'file_sxw': base64.encodestring(report.report_sxw_content)}
|
||||
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': intro_form,
|
||||
'fields': intro_fields,
|
||||
'state': [
|
||||
('end','Cancel'),
|
||||
('get_form','Modify a report')
|
||||
]
|
||||
}
|
||||
},
|
||||
'get_form': {
|
||||
'actions': [_get_default],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': get_form,
|
||||
'fields': get_fields,
|
||||
'state': [
|
||||
('end','Cancel'),
|
||||
('get_form_result', 'Continue'),
|
||||
]
|
||||
}
|
||||
},
|
||||
'get_form_result': {
|
||||
'actions': [_get_report],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': get_form_result,
|
||||
'fields': get_form_fields,
|
||||
'state': [
|
||||
('end','Close'),
|
||||
('send_form', 'Upload the modified report'),
|
||||
]
|
||||
}
|
||||
},
|
||||
'send_form': {
|
||||
'actions': [_upload_report_clear],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': send_form_arch,
|
||||
'fields': send_form_fields,
|
||||
'state': [
|
||||
('end','Close'),
|
||||
('send_form_result', 'Update the report'),
|
||||
]
|
||||
}
|
||||
},
|
||||
'send_form_result': {
|
||||
'actions': [_upload_report],
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'arch': send_form_result_arch,
|
||||
'fields': send_form_result_fields,
|
||||
'state': [
|
||||
('end','Close'),
|
||||
]
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
base_report_designer_modify('base_report_designer.modify')
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2004 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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 tiny_sxw2rml import sxw2rml
|
|
@ -1,681 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xsl:stylesheet
|
||||
version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:fo="http://www.w3.org/1999/XSL/Format"
|
||||
xmlns:office="http://openoffice.org/2000/office"
|
||||
xmlns:style="http://openoffice.org/2000/style"
|
||||
xmlns:text="http://openoffice.org/2000/text"
|
||||
xmlns:table="http://openoffice.org/2000/table"
|
||||
xmlns:draw="http://openoffice.org/2000/drawing"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:number="http://openoffice.org/2000/datastyle"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:chart="http://openoffice.org/2000/chart"
|
||||
xmlns:dr3d="http://openoffice.org/2000/dr3d"
|
||||
xmlns:math="http://www.w3.org/1998/Math/MathML"
|
||||
xmlns:form="http://openoffice.org/2000/form"
|
||||
xmlns:script="http://openoffice.org/2000/script"
|
||||
office:class="text" office:version="1.0"
|
||||
exclude-result-prefixes = "xsl fo office style text table draw xlink number svg chart dr3d math form script">
|
||||
|
||||
<!--TODO's: indent, picture cache (trml2pdf) -->
|
||||
|
||||
<xsl:output method="xml" indent="yes" />
|
||||
<xsl:strip-space elements="*"/>
|
||||
|
||||
<xsl:key name="text_style" match="style:style[@style:family='text']" use="@style:name" />
|
||||
<xsl:key name="page_break_before" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-before='page']" use="@style:name" />
|
||||
<xsl:key name="page_break_after" match="style:style[@style:family='paragraph' and ./style:properties/@fo:break-after='page']" use="@style:name" />
|
||||
<xsl:key name="table_column_style" match="style:style[@style:family='table-column']" use="@style:name" />
|
||||
<xsl:key name="table_cell_style" match="style:style[@style:family='table-cell']" use="@style:name" />
|
||||
<xsl:key name="paragraph_style" match="style:style[@style:family='paragraph']" use="@style:name" />
|
||||
|
||||
<xsl:template match="office:document-content">
|
||||
<document filename="test.pdf">
|
||||
<xsl:apply-templates select="office:automatic-styles" />
|
||||
<xsl:apply-templates select="office:body" />
|
||||
</document>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="page_size">
|
||||
<xsl:attribute name="pageSize">
|
||||
<xsl:text>(</xsl:text>
|
||||
<xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
|
||||
<xsl:text>,</xsl:text>
|
||||
<xsl:value-of select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
|
||||
<xsl:text>)</xsl:text>
|
||||
</xsl:attribute>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="fixed_frame">
|
||||
<xsl:for-each select="//draw:text-box">
|
||||
<frame>
|
||||
<xsl:attribute name="id"><xsl:value-of select="./@draw:name" /></xsl:attribute>
|
||||
<xsl:attribute name="x1"><xsl:value-of select="./@svg:x" /></xsl:attribute>
|
||||
<xsl:attribute name="y1">
|
||||
<xsl:value-of
|
||||
select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height - ./@svg:y - ./@fo:min-height" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="width">
|
||||
<xsl:value-of select="./@svg:width" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="height">
|
||||
<xsl:value-of select="./@fo:min-height" />
|
||||
</xsl:attribute>
|
||||
</frame>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="margin_sizes">
|
||||
<xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
|
||||
<xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
|
||||
<xsl:variable name="margin_top" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-top" />
|
||||
<xsl:variable name="margin_bottom" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-bottom" />
|
||||
<xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
|
||||
<xsl:variable name="page_height" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-height" />
|
||||
<xsl:attribute name="x1"><xsl:value-of select="$margin_left" /></xsl:attribute>
|
||||
<xsl:attribute name="y1"><xsl:value-of select="$margin_bottom" /></xsl:attribute>
|
||||
<xsl:attribute name="width"><xsl:value-of select="$page_width - $margin_left - $margin_right"/></xsl:attribute>
|
||||
<xsl:attribute name="height"><xsl:value-of select="$page_height - $margin_bottom - $margin_top"/></xsl:attribute>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="text_width">
|
||||
<!-- You need this for the workaround to make primitive outlines-->
|
||||
<xsl:variable name="margin_left" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-left" />
|
||||
<xsl:variable name="margin_right" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:margin-right" />
|
||||
<xsl:variable name="page_width" select="//transferredfromstylesxml/style:page-master[1]/style:properties/@fo:page-width" />
|
||||
<xsl:value-of select="$page_width - $margin_left - $margin_right - 18"/>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
|
||||
<xsl:template match="office:automatic-styles">
|
||||
<!--<template pageSize="(21cm, 29.7cm)" leftMargin="1.0cm" rightMargin="2.0cm" topMargin="1.0cm" bottomMargin="1.0cm" title="Test" author="Martin Simon" allowSplitting="20">-->
|
||||
<template pageSize="(21cm, 29.7cm)" title="Test" author="Martin Simon" allowSplitting="20">
|
||||
<xsl:call-template name="page_size" />
|
||||
<pageTemplate id="first">
|
||||
<xsl:call-template name="fixed_frame" />
|
||||
<frame id="first" x1="2cm" y1="2cm" width="17cm" height="26cm">
|
||||
<xsl:call-template name="margin_sizes" />
|
||||
</frame>
|
||||
</pageTemplate>
|
||||
</template>
|
||||
<stylesheet>
|
||||
<!--A table style to simulate primitive outlines -till the <addOutline> tag is implemented in trml2pdf -->
|
||||
<blockTableStyle id="Standard_Outline">
|
||||
<blockAlignment value="LEFT"/>
|
||||
<blockValign value="TOP"/>
|
||||
</blockTableStyle>
|
||||
<!--use two standard table grid styles like PyOpenOffice "Old Way": with and without a grid-->
|
||||
<!--TODO insert table cell colors here, not within the <td> tag - otherwise
|
||||
it will not work with flowables as cell content-->
|
||||
<xsl:call-template name="make_blocktablestyle" />
|
||||
<initialize>
|
||||
<paraStyle name="all" alignment="justify" />
|
||||
</initialize>
|
||||
<xsl:apply-templates select="style:style" />
|
||||
</stylesheet>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_blocktablestyle">
|
||||
<xsl:for-each select="//table:table">
|
||||
<xsl:variable name="test">
|
||||
<xsl:value-of select="./@table:name" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not(boolean(count(preceding-sibling::table:table[@table:name=$test])))">
|
||||
<!--Test if this is the first table with this style, nested tables not counted-->
|
||||
<blockTableStyle id="{@table:name}">
|
||||
<xsl:if test=".//draw:image">
|
||||
<blockTopPadding value="0"/>
|
||||
<blockBottomPadding value="0"/>
|
||||
</xsl:if>
|
||||
<blockAlignment value="LEFT" />
|
||||
<blockValign value="TOP" />
|
||||
<xsl:call-template name="make_linestyle" />
|
||||
<xsl:call-template name="make_tablebackground" />
|
||||
</blockTableStyle>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_linestyle">
|
||||
<xsl:for-each select=".//table:table-row">
|
||||
<xsl:variable name="row" select="position() - 1"/>
|
||||
<xsl:for-each select=".//table:table-cell">
|
||||
<xsl:variable name="col" select="position() - 1"/>
|
||||
<xsl:variable name="linebefore">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-left"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($linebefore='') and not($linebefore='none')">
|
||||
<xsl:variable name="colorname">
|
||||
<xsl:value-of select="substring-after($linebefore,'#')"/>
|
||||
</xsl:variable>
|
||||
<lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
|
||||
</xsl:if>
|
||||
<xsl:variable name="lineafter">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-right"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($lineafter='') and not($lineafter='none')">
|
||||
<xsl:variable name="colorname">
|
||||
<xsl:value-of select="substring-after($lineafter,'#')"/>
|
||||
</xsl:variable>
|
||||
<lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
|
||||
</xsl:if>
|
||||
<xsl:variable name="lineabove">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-top"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($lineabove='') and not($lineabove='none')">
|
||||
<xsl:variable name="colorname">
|
||||
<xsl:value-of select="substring-after($lineabove,'#')"/>
|
||||
</xsl:variable>
|
||||
<lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
|
||||
</xsl:if>
|
||||
<xsl:variable name="linebelow">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border-bottom"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($linebelow='') and not($linebelow='none')">
|
||||
<xsl:variable name="colorname">
|
||||
<xsl:value-of select="substring-after($linebelow,'#')"/>
|
||||
</xsl:variable>
|
||||
<lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
|
||||
</xsl:if>
|
||||
<xsl:variable name="grid">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:border"/>
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($grid='') and not($grid='none')">
|
||||
<xsl:variable name="colorname">
|
||||
<xsl:value-of select="substring-after($grid,'#')"/>
|
||||
</xsl:variable>
|
||||
<!-- Don't use grid because we don't need a line between each rows -->
|
||||
<lineStyle kind="LINEBEFORE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
|
||||
<lineStyle kind="LINEAFTER" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},-1"/>
|
||||
<lineStyle kind="LINEABOVE" colorName="#{$colorname}" start="{$col},{$row}" stop="{$col},{$row}"/>
|
||||
<lineStyle kind="LINEBELOW" colorName="#{$colorname}" start="{$col},{-1}" stop="{$col},{-1}"/>
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<!-- Was needed to simulate bulleted lists:
|
||||
<xsl:template match="text:ordered-list|text:unordered-list">
|
||||
<xsl:variable name = "text_width">
|
||||
<xsl:call-template name="text_width" />
|
||||
</xsl:variable>
|
||||
<blockTable style="Standard_Outline" colWidths="18,{$text_width}">
|
||||
<xsl:apply-templates match="text:list-item" />
|
||||
</blockTable>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text:list-item">
|
||||
<tr>
|
||||
<td><para><font face="Helvetica-Bold" size="10">*</font></para></td>
|
||||
<td>
|
||||
<xsl:apply-templates />
|
||||
</td>
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
-->
|
||||
|
||||
|
||||
<xsl:template match="office:body">
|
||||
<story>
|
||||
<xsl:apply-templates />
|
||||
<xsl:for-each select="//draw:text-box">
|
||||
<currentFrame>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="./@draw:name" />
|
||||
</xsl:attribute>
|
||||
</currentFrame>
|
||||
<xsl:apply-templates>
|
||||
<xsl:with-param name="skip_draw" select="0" />
|
||||
</xsl:apply-templates>
|
||||
<frameEnd />
|
||||
</xsl:for-each>
|
||||
</story>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="table:table">
|
||||
<blockTable>
|
||||
<xsl:attribute name="colWidths">
|
||||
<xsl:call-template name="make_columns" />
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="make_tableheaders" />
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="@table:name" />
|
||||
</xsl:attribute>
|
||||
<xsl:apply-templates />
|
||||
</blockTable>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_tableheaders">
|
||||
<xsl:if test="boolean(count(table:table-header-rows))">
|
||||
<xsl:attribute name="repeatRows">1</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_tablebackground">
|
||||
<xsl:for-each select=".//table:table-row">
|
||||
<!--Be careful when there are table:table-header-rows as
|
||||
parent node of table:table-row -->
|
||||
<xsl:variable name="row" select="position() - 1" />
|
||||
<xsl:for-each select="./table:table-cell">
|
||||
<xsl:variable name="col" select="position() - 1" />
|
||||
<xsl:variable name="background">
|
||||
<xsl:value-of select="key('table_cell_style',@table:style-name)/style:properties/@fo:background-color" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($background='') and boolean(key('table_cell_style',@table:style-name)/style:properties/@fo:background-color) and starts-with($background,'#')">
|
||||
<!--only RGB hexcolors are accepted -->
|
||||
<blockBackground colorName="{$background}" start="{$col},{$row}" stop="{$col},-1" />
|
||||
</xsl:if>
|
||||
</xsl:for-each>
|
||||
</xsl:for-each>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_columns">
|
||||
<xsl:variable name="columns" >
|
||||
<xsl:for-each select="table:table-column">
|
||||
<xsl:value-of select="key('table_column_style',@table:style-name)/style:properties/@style:column-width" />
|
||||
<xsl:text>,</xsl:text>
|
||||
</xsl:for-each>
|
||||
</xsl:variable>
|
||||
<xsl:value-of select="substring($columns,1,string-length($columns) - 1)" />
|
||||
<!--strip the last comma-->
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="table:table-row">
|
||||
<tr>
|
||||
<xsl:apply-templates />
|
||||
</tr>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="table:table-cell">
|
||||
<td>
|
||||
<xsl:apply-templates />
|
||||
</td>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text:section">
|
||||
<section>
|
||||
<xsl:apply-templates />
|
||||
</section>
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="text:span">
|
||||
<font>
|
||||
<xsl:call-template name="make_fontnames_span" />
|
||||
<xsl:call-template name="make_fontsize_span" />
|
||||
<xsl:apply-templates />
|
||||
</font>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_fontsize_span">
|
||||
<xsl:variable name ="fontsize">
|
||||
<xsl:value-of select="key('text_style',@text:style-name)/style:properties/@fo:font-size" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($fontsize='') and boolean(key('text_style',@text:style-name)/style:properties/@fo:font-size)" >
|
||||
<xsl:attribute name="size">
|
||||
<xsl:value-of select="$fontsize" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_fontnames_span">
|
||||
<xsl:attribute name="face">
|
||||
<xsl:call-template name="make_fontnames">
|
||||
<xsl:with-param name="fontName" select="key('text_style',@text:style-name)/style:properties/@style:font-name" />
|
||||
<xsl:with-param name="fontWeight" select="key('text_style',@text:style-name)/style:properties/@fo:font-weight" />
|
||||
<xsl:with-param name="fontStyle" select="key('text_style',@text:style-name)/style:properties/@fo:font-style" />
|
||||
</xsl:call-template>
|
||||
</xsl:attribute>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_image">
|
||||
<illustration height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}">
|
||||
<image x="0" y="0" file="{substring-after(.//draw:image/@xlink:href,'#Pictures/')}" height="{.//draw:image/@svg:height}" width="{.//draw:image/@svg:width}" />
|
||||
</illustration>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="empty_paragraph">
|
||||
<xsl:if test="not(boolean(count(descendant::node())))">
|
||||
<xsl:call-template name="distance_point">
|
||||
<xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
|
||||
</xsl:call-template>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="distance_point">
|
||||
<xsl:param name="background" />
|
||||
<xsl:param name="tab_stop"></xsl:param>
|
||||
<xsl:variable name="local_back">
|
||||
<xsl:choose>
|
||||
<xsl:when test="not(boolean($background)) or not(contains($background,'#'))">
|
||||
<!-- Do not accept OO colors like "transparent", only hex-colors -->
|
||||
<xsl:text>white</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:value-of select="$background" />
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:variable>
|
||||
<font color="{$local_back}">
|
||||
<xsl:text> </xsl:text>
|
||||
<xsl:if test="boolean($tab_stop)">
|
||||
<!-- simulate a tabstop with white/background-color points -->
|
||||
<xsl:text>.........</xsl:text>
|
||||
</xsl:if>
|
||||
</font>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text:ordered-list">
|
||||
<xsl:apply-templates />
|
||||
<para><seqreset id="ordered_list" /></para>
|
||||
<!-- Reset the counter. seqreset is not a trml2pdf tag, but a Platypus Intra Paragraph Markup,
|
||||
so it needs a dummy paragraph to enclose it -->
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_listitem">
|
||||
<xsl:if test="(name(..)='text:list-item')">
|
||||
<xsl:attribute name="leftIndent">15</xsl:attribute>
|
||||
<xsl:attribute name="bulletIndent">0</xsl:attribute>
|
||||
<xsl:choose>
|
||||
<xsl:when test="(name(../..)='text:unordered-list')">
|
||||
<xsl:variable name="fontsize">
|
||||
<xsl:value-of select="number(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)" />
|
||||
</xsl:variable>
|
||||
<xsl:choose>
|
||||
<xsl:when test="$fontsize='NaN'">
|
||||
<!-- you should exclude non-numerical values for bulletFontSize. <== Sometimes the preprocessing went wrong.-->
|
||||
<!--use a default bullet font size-->
|
||||
<xsl:attribute name="bulletFontSize">6</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:attribute name="bulletFontSize"><xsl:value-of select="floor(($fontsize div 2) + 1)" /></xsl:attribute>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:attribute name="bulletFontName">ZapfDingbats</xsl:attribute>
|
||||
<xsl:attribute name="bulletText">l</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!-- Generate the numbers for an ordered list -->
|
||||
<xsl:variable name="size">
|
||||
<xsl:value-of select="key('paragraph_style',@text:style-name)/style:properties/@fo:font-size" />
|
||||
</xsl:variable>
|
||||
<!-- For ordered lists we use the bullet tag from Platypus Intra Paragraph Markup -->
|
||||
<bullet>
|
||||
<xsl:if test="not($size='') and boolean(key('paragraph_style',@text:style-name)/style:properties/@fo:font-size)">
|
||||
<xsl:attribute name="size">
|
||||
<!-- adapt the fontsize to the fontsize of the current paragraph -->
|
||||
<xsl:value-of select="$size" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<seq id="ordered_list" />.</bullet>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text:drop-down">
|
||||
<xsl:value-of select="text:label[2]/@text:value" />
|
||||
</xsl:template>
|
||||
|
||||
|
||||
<xsl:template match="text:p|text:h">
|
||||
<xsl:param name="skip_draw" select="1" />
|
||||
<xsl:if test="boolean(key('page_break_before',@text:style-name))" >
|
||||
<pageBreak />
|
||||
</xsl:if>
|
||||
<xsl:choose>
|
||||
<xsl:when test="boolean(.//draw:image)">
|
||||
<xsl:call-template name="make_image" />
|
||||
</xsl:when>
|
||||
<xsl:when test="boolean(name(..) = 'draw:text-box') and boolean($skip_draw)">
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<para>
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="@text:style-name" />
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="make_listitem" />
|
||||
<xsl:apply-templates />
|
||||
<xsl:call-template name="empty_paragraph" />
|
||||
</para>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
<xsl:if test="boolean(key('page_break_after',@text:style-name))" >
|
||||
<pageBreak />
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="text:p/text:tab-stop">
|
||||
<!-- simulate a tabstop -->
|
||||
<xsl:call-template name="distance_point">
|
||||
<xsl:with-param name="background" select="key('paragraph_style',@text:style-name)/style:properties/@fo:background-color" />
|
||||
<xsl:with-param name="tab_stop">yes</xsl:with-param>
|
||||
</xsl:call-template>
|
||||
</xsl:template>
|
||||
|
||||
<!-- experimental - switched off
|
||||
<xsl:template match="text:h">
|
||||
<para>
|
||||
<xsl:attribute name="style">
|
||||
<xsl:value-of select="@text:style-name" />
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="make_number" />
|
||||
<xsl:apply-templates />
|
||||
<xsl:call-template name="empty_paragraph" />
|
||||
</para>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_number">
|
||||
<xsl:choose>
|
||||
<xsl:when test="@text:level='1'">
|
||||
<xsl:number format="1. " />
|
||||
</xsl:when>
|
||||
<xsl:when test="@text:level='2'">
|
||||
<xsl:number count="text:h[@text:level='1']|text:h[text:level='2']" level="any" format="1.1." />
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
-->
|
||||
|
||||
<xsl:template match="style:style[@style:family='paragraph']">
|
||||
<paraStyle>
|
||||
<xsl:attribute name="name">
|
||||
<xsl:value-of select="@style:name" />
|
||||
</xsl:attribute>
|
||||
<xsl:call-template name="make_indent_paragraph" />
|
||||
<xsl:call-template name="make_fontnames_paragraph" />
|
||||
<xsl:call-template name="make_fontsize" />
|
||||
<!--<xsl:call-template name="make_parent" /> not necessary -
|
||||
parent styles processed by PyOpenOffice -->
|
||||
<xsl:call-template name="make_alignment" />
|
||||
<xsl:call-template name="make_background" />
|
||||
<xsl:call-template name="make_space_beforeafter" />
|
||||
</paraStyle>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_indent_paragraph">
|
||||
<xsl:variable name="right_indent"><xsl:value-of select="style:properties/@fo:margin-right" /></xsl:variable>
|
||||
<xsl:variable name="left_indent"><xsl:value-of select="style:properties/@fo:margin-left" /></xsl:variable>
|
||||
<xsl:if test="not($right_indent='') and boolean(style:properties/@fo:margin-right)">
|
||||
<xsl:attribute name="rightIndent">
|
||||
<xsl:value-of select="$right_indent" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:if test="not($left_indent='') and boolean(style:properties/@fo:margin-left)">
|
||||
<xsl:attribute name="leftIndent">
|
||||
<xsl:value-of select="$left_indent" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_background">
|
||||
<xsl:variable name="background">
|
||||
<xsl:value-of select="style:properties/@fo:background-color" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($background='') and boolean(style:properties/@fo:background-color) and starts-with($background,'#')" >
|
||||
<xsl:attribute name="backColor">
|
||||
<xsl:value-of select="$background" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_space_beforeafter">
|
||||
<xsl:variable name="before">
|
||||
<xsl:value-of select="style:properties/@fo:margin-top" />
|
||||
</xsl:variable>
|
||||
<xsl:variable name="after">
|
||||
<xsl:value-of select="style:properties/@fo:margin-bottom" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($before='') and boolean(style:properties/@fo:margin-top)" >
|
||||
<xsl:attribute name="spaceBefore">
|
||||
<xsl:value-of select="$before" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
<xsl:if test="not($after='') and boolean(style:properties/@fo:margin-bottom)" >
|
||||
<xsl:attribute name="spaceAfter">
|
||||
<xsl:value-of select="$after" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_fontsize">
|
||||
<xsl:variable name="fontSize">
|
||||
<xsl:value-of select="style:properties/@fo:font-size" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($fontSize='') and boolean(style:properties/@fo:font-size)">
|
||||
<xsl:attribute name="fontSize">
|
||||
<xsl:value-of select="$fontSize" />
|
||||
</xsl:attribute>
|
||||
<xsl:attribute name="leading">
|
||||
<xsl:value-of select="$fontSize + floor($fontSize div 5) + 1" />
|
||||
<!--use a standard leading related to the font size -->
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<!--this template is not needed anymore for "normalized" sxw files -->
|
||||
<xsl:template name="make_parent">
|
||||
<xsl:variable name="parent">
|
||||
<xsl:value-of select="@style:parent-style-name" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($parent='') and boolean(@style:parent-style-name)">
|
||||
<xsl:attribute name="parent">
|
||||
<xsl:value-of select="$parent" />
|
||||
</xsl:attribute>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_alignment">
|
||||
<xsl:variable name="alignment">
|
||||
<xsl:value-of select="style:properties/@fo:text-align" />
|
||||
</xsl:variable>
|
||||
<xsl:if test="not($alignment='') and boolean(style:properties/@fo:text-align)">
|
||||
<xsl:choose>
|
||||
<xsl:when test="$alignment='start'">
|
||||
<xsl:attribute name="alignment">LEFT</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="$alignment='center'">
|
||||
<xsl:attribute name="alignment">CENTER</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="$alignment='end'">
|
||||
<xsl:attribute name="alignment">RIGHT</xsl:attribute>
|
||||
</xsl:when>
|
||||
<xsl:when test="$alignment='justify'">
|
||||
<xsl:attribute name="alignment">JUSTIFY</xsl:attribute>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_fontnames_paragraph">
|
||||
<xsl:attribute name="fontName">
|
||||
<xsl:call-template name="make_fontnames">
|
||||
<xsl:with-param name="fontName" select="style:properties/@style:font-name" />
|
||||
<xsl:with-param name="fontWeight" select="style:properties/@fo:font-weight" />
|
||||
<xsl:with-param name="fontStyle" select="style:properties/@fo:font-style" />
|
||||
</xsl:call-template>
|
||||
</xsl:attribute>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template name="make_fontnames">
|
||||
<!--much too verbose, needs improvement-->
|
||||
<xsl:param name="fontName" />
|
||||
<xsl:param name="fontWeight" />
|
||||
<xsl:param name="fontStyle" />
|
||||
<xsl:choose>
|
||||
<xsl:when test="not($fontName='') and boolean($fontName)">
|
||||
<xsl:choose>
|
||||
<xsl:when test="contains($fontName,'Courier')">
|
||||
<xsl:choose>
|
||||
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Courier-BoldOblique</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
|
||||
<xsl:text>Courier-Bold</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Courier-Oblique</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>Courier</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:when test="contains($fontName,'Helvetica') or contains($fontName,'Arial') or contains($fontName,'Sans')">
|
||||
<xsl:choose>
|
||||
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Helvetica-BoldOblique</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
|
||||
<xsl:text>Helvetica-Bold</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Helvetica-Oblique</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>Helvetica</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:choose>
|
||||
<xsl:when test="($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Times-BoldItalic</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="($fontWeight='bold') and not ($fontStyle='italic')">
|
||||
<xsl:text>Times-Bold</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:when test="not($fontWeight='bold') and ($fontStyle='italic')">
|
||||
<xsl:text>Times-Italic</xsl:text>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<xsl:text>Times-Roman</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:when>
|
||||
<xsl:otherwise>
|
||||
<!--Use this as default -->
|
||||
<xsl:text>Times-Roman</xsl:text>
|
||||
</xsl:otherwise>
|
||||
</xsl:choose>
|
||||
</xsl:template>
|
||||
|
||||
<!--
|
||||
This stylesheet is part of:
|
||||
PyOpenOffice Version 0.4
|
||||
Copyright (C) 2005: Martin Simon
|
||||
Homepage: www.bezirksreiter.de
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999
|
||||
-->
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
|
|
@ -1,365 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
#coding: utf-8
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright (c):
|
||||
#
|
||||
# 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
|
||||
# 2005 Fabien Pinckaers, TINY SPRL. (http://tiny.be)
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
"""
|
||||
Tiny SXW2RML - The Tiny ERP's report engine
|
||||
|
||||
Tiny SXW2RMLis part of the Tiny report project.
|
||||
Tiny Report is a module that allows you to render high quality PDF document
|
||||
from an OpenOffice template (.sxw) and any relationnal database.
|
||||
|
||||
The whole source code is distributed under the terms of the
|
||||
GNU Public Licence.
|
||||
|
||||
(c) 2005 pyopenoffice.py Martin Simon (http://www.bezirksreiter.de)
|
||||
(c) 2005-TODAY, Fabien Pinckaers - Tiny sprl
|
||||
"""
|
||||
__version__ = '0.9'
|
||||
|
||||
|
||||
import re
|
||||
import string
|
||||
import os
|
||||
import zipfile
|
||||
import xml.dom.minidom
|
||||
from reportlab.lib.units import toLength
|
||||
import base64
|
||||
|
||||
class DomApiGeneral:
|
||||
"""General DOM API utilities."""
|
||||
def __init__(self,content_string="",file=""):
|
||||
self.content_string = content_string
|
||||
self.re_digits = re.compile(r"(.*?\d)(pt|cm|mm|inch|in)")
|
||||
|
||||
def _unitTuple(self,string):
|
||||
"""Split values and units to a tuple."""
|
||||
temp = self.re_digits.findall(string)
|
||||
if not temp:
|
||||
return (string,"")
|
||||
else:
|
||||
return (temp[0])
|
||||
|
||||
def stringPercentToFloat(self,string):
|
||||
temp = string.replace("""%""","")
|
||||
return float(temp)/100
|
||||
|
||||
def findChildrenByName(self,parent,name,attr_dict={}):
|
||||
"""Helper functions. Does not work recursively.
|
||||
Optional: also test for certain attribute/value pairs."""
|
||||
children = []
|
||||
for c in parent.childNodes:
|
||||
if c.nodeType == c.ELEMENT_NODE and c.nodeName == name:
|
||||
children.append(c)
|
||||
if attr_dict == {}:
|
||||
return children
|
||||
else:
|
||||
return self._selectForAttributes(nodelist=children,attr_dict=attr_dict)
|
||||
|
||||
def _selectForAttributes(self,nodelist,attr_dict):
|
||||
"Helper function."""
|
||||
selected_nodes = []
|
||||
for n in nodelist:
|
||||
check = 1
|
||||
for a in attr_dict.keys():
|
||||
if n.getAttribute(a) != attr_dict[a]:
|
||||
# at least one incorrect attribute value?
|
||||
check = 0
|
||||
if check:
|
||||
selected_nodes.append(n)
|
||||
return selected_nodes
|
||||
|
||||
def _stringToTuple(self,s):
|
||||
"""Helper function."""
|
||||
try:
|
||||
temp = string.split(s,",")
|
||||
return int(temp[0]),int(temp[1])
|
||||
except:
|
||||
return None
|
||||
|
||||
def _tupleToString(self,t):
|
||||
try:
|
||||
return self.openOfficeStringUtf8("%s,%s" % (t[0],t[1]))
|
||||
except:
|
||||
return None
|
||||
|
||||
def _lengthToFloat(self,value):
|
||||
v = value
|
||||
if not self.re_digits.search(v):
|
||||
return v
|
||||
try:
|
||||
if v[-4:] == "inch":
|
||||
# OO files use "inch" instead of "in" in Reportlab units
|
||||
v = v[:-2]
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
c = round(toLength(v))
|
||||
return c
|
||||
except:
|
||||
return v
|
||||
|
||||
def openOfficeStringUtf8(self,string):
|
||||
if type(string) == unicode:
|
||||
return string.encode("utf-8")
|
||||
tempstring = unicode(string,"cp1252").encode("utf-8")
|
||||
return tempstring
|
||||
|
||||
class DomApi(DomApiGeneral):
|
||||
"""This class provides a DOM-API for XML-Files from an SXW-Archive."""
|
||||
def __init__(self,xml_content,xml_styles):
|
||||
DomApiGeneral.__init__(self)
|
||||
self.content_dom = xml.dom.minidom.parseString(xml_content)
|
||||
self.styles_dom = xml.dom.minidom.parseString(xml_styles)
|
||||
body = self.content_dom.getElementsByTagName("office:body")
|
||||
self.body = body and body[0]
|
||||
|
||||
# TODO:
|
||||
self.style_dict = {}
|
||||
self.style_properties_dict = {}
|
||||
|
||||
# ******** always use the following order:
|
||||
self.buildStyleDict()
|
||||
self.buildStylePropertiesDict()
|
||||
if self.styles_dom.getElementsByTagName("style:page-master").__len__()<>0:
|
||||
self.page_master = self.styles_dom.getElementsByTagName("style:page-master")[0]
|
||||
self.document = self.content_dom.getElementsByTagName("office:document-content")[0]
|
||||
|
||||
def buildStylePropertiesDict(self):
|
||||
for s in self.style_dict.keys():
|
||||
self.style_properties_dict[s] = self.getStylePropertiesDict(s)
|
||||
|
||||
def updateWithPercents(self,dict,updatedict):
|
||||
"""Sometimes you find values like "115%" in the style hierarchy."""
|
||||
if not updatedict:
|
||||
# no style hierarchies for this style? =>
|
||||
return
|
||||
new_updatedict = copy.copy(updatedict)
|
||||
for u in new_updatedict.keys():
|
||||
try:
|
||||
if new_updatedict[u].find("""%""") != -1 and dict.has_key(u):
|
||||
number = float(self.re_digits.search(dict[u]).group(1))
|
||||
unit = self.re_digits.search(dict[u]).group(2)
|
||||
new_number = self.stringPercentToFloat(new_updatedict[u]) * number
|
||||
if unit == "pt":
|
||||
new_number = int(new_number)
|
||||
# no floats allowed for "pt"
|
||||
# OOo just takes the int, does not round (try it out!)
|
||||
new_updatedict[u] = "%s%s" % (new_number,unit)
|
||||
else:
|
||||
dict[u] = new_updatedict[u]
|
||||
except:
|
||||
dict[u] = new_updatedict[u]
|
||||
dict.update(new_updatedict)
|
||||
|
||||
def normalizeStyleProperties(self):
|
||||
"""Transfer all style:style-properties attributes from the
|
||||
self.style_properties_hierarchical dict to the automatic-styles
|
||||
from content.xml. Use this function to preprocess content.xml for
|
||||
XSLT transformations etc.Do not try to implement this function
|
||||
with XSlT - believe me, it's a terrible task..."""
|
||||
styles_styles = self.styles_dom.getElementsByTagName("style:style")
|
||||
automatic_styles = self.content_dom.getElementsByTagName("office:automatic-styles")[0]
|
||||
for s in styles_styles:
|
||||
automatic_styles.appendChild(s.cloneNode(deep=1))
|
||||
content_styles = self.content_dom.getElementsByTagName("style:style")
|
||||
# these are the content_styles with styles_styles added!!!
|
||||
for s in content_styles:
|
||||
c = self.findChildrenByName(s,"style:properties")
|
||||
if c == []:
|
||||
# some derived automatic styles do not have "style:properties":
|
||||
temp = self.content_dom.createElement("style:properties")
|
||||
s.appendChild(temp)
|
||||
c = self.findChildrenByName(s,"style:properties")
|
||||
c = c[0]
|
||||
dict = self.style_properties_dict[(s.getAttribute("style:name")).encode("latin-1")] or {}
|
||||
for attribute in dict.keys():
|
||||
c.setAttribute(self.openOfficeStringUtf8(attribute),self.openOfficeStringUtf8(dict[attribute]))
|
||||
|
||||
def transferStylesXml(self):
|
||||
"""Transfer certain sub-trees from styles.xml to the normalized content.xml
|
||||
(see above). It is not necessary to do this - for example - with paragraph styles.
|
||||
the "normalized" style properties contain all information needed for
|
||||
further processing."""
|
||||
# TODO: What about table styles etc.?
|
||||
outline_styles = self.styles_dom.getElementsByTagName("text:outline-style")
|
||||
t = self.content_dom.createElement("transferredfromstylesxml")
|
||||
self.document.insertBefore(t,self.body)
|
||||
t_new = self.body.previousSibling
|
||||
try:
|
||||
page_master = self.page_master
|
||||
t_new.appendChild(page_master.cloneNode(deep=1))
|
||||
t_new.appendChild(outline_styles[0].cloneNode(deep=1))
|
||||
except:
|
||||
pass
|
||||
|
||||
def normalizeLength(self):
|
||||
"""Normalize all lengthes to floats (i.e: 1 inch = 72).
|
||||
Always use this after "normalizeContent" and "transferStyles"!"""
|
||||
# TODO: The complex attributes of table cell styles are not transferred yet.
|
||||
#all_styles = self.content_dom.getElementsByTagName("style:properties")
|
||||
#all_styles += self.content_dom.getElementsByTagName("draw:image")
|
||||
all_styles = self.content_dom.getElementsByTagName("*")
|
||||
for s in all_styles:
|
||||
for x in s._attrs.keys():
|
||||
v = s.getAttribute(x)
|
||||
s.setAttribute(x,"%s" % self._lengthToFloat(v))
|
||||
# convert float to string first!
|
||||
|
||||
def normalizeTableColumns(self):
|
||||
"""Handle this strange table:number-columns-repeated attribute."""
|
||||
columns = self.content_dom.getElementsByTagName("table:table-column")
|
||||
for c in columns:
|
||||
if c.hasAttribute("table:number-columns-repeated"):
|
||||
number = int(c.getAttribute("table:number-columns-repeated"))
|
||||
c.removeAttribute("table:number-columns-repeated")
|
||||
for i in range(number-1):
|
||||
(c.parentNode).insertBefore(c.cloneNode(deep=1),c)
|
||||
|
||||
def buildStyleDict(self):
|
||||
"""Store all style:style-nodes from content.xml and styles.xml in self.style_dict.
|
||||
Caution: in this dict the nodes from two dom apis are merged!"""
|
||||
for st in (self.styles_dom,self.content_dom):
|
||||
for s in st.getElementsByTagName("style:style"):
|
||||
name = s.getAttribute("style:name").encode("latin-1")
|
||||
self.style_dict[name] = s
|
||||
return True
|
||||
|
||||
def toxml(self):
|
||||
return self.content_dom.toxml(encoding="utf-8")
|
||||
|
||||
def getStylePropertiesDict(self,style_name):
|
||||
res = {}
|
||||
|
||||
if self.style_dict[style_name].hasAttribute("style:parent-style-name"):
|
||||
parent = self.style_dict[style_name].getAttribute("style:parent-style-name").encode("latin-1")
|
||||
res = self.getStylePropertiesDict(parent)
|
||||
|
||||
childs = self.style_dict[style_name].childNodes
|
||||
for c in childs:
|
||||
if c.nodeType == c.ELEMENT_NODE and c.nodeName == "style:properties":
|
||||
for attr in c._attrs.keys():
|
||||
res[attr] = c.getAttribute(attr).encode("latin-1")
|
||||
return res
|
||||
|
||||
class PyOpenOffice(object):
|
||||
"""This is the main class which provides all functionality."""
|
||||
def __init__(self, path='.', save_pict=False):
|
||||
self.path = path
|
||||
self.save_pict = save_pict
|
||||
self.images = {}
|
||||
|
||||
def oo_read(self,fname):
|
||||
z = zipfile.ZipFile(fname,"r")
|
||||
content = z.read('content.xml')
|
||||
style = z.read('styles.xml')
|
||||
all = z.namelist()
|
||||
for a in all:
|
||||
if a[:9]=='Pictures/' and len(a)>10:
|
||||
pic_content = z.read(a)
|
||||
self.images[a[9:]] = pic_content
|
||||
if self.save_pict:
|
||||
f=open(os.path.join(self.path, os.path.basename(a)),"wb")
|
||||
f.write(pic_content)
|
||||
f.close()
|
||||
z.close()
|
||||
return content,style
|
||||
|
||||
def oo_replace(self,content):
|
||||
regex = [
|
||||
(r"<para[^>]*/>", ""),
|
||||
#(r"<text:ordered-list.*?>(.*?)</text:ordered-list>", "$1"),
|
||||
#(r"<text:unordered-list.*?>(.*?)</text:unordered-list>", "$1"),
|
||||
(r"<para(.*)>(.*?)<text:line-break[^>]*/>", "<para$1>$2</para><para$1>"),
|
||||
]
|
||||
for key,val in regex:
|
||||
content = re.sub(key, val, content)
|
||||
return content
|
||||
|
||||
def unpackNormalize(self,sourcefile):
|
||||
c,s = self.oo_read(sourcefile)
|
||||
c = self.oo_replace(c)
|
||||
dom = DomApi(c,s)
|
||||
dom.normalizeStyleProperties()
|
||||
dom.transferStylesXml()
|
||||
dom.normalizeLength()
|
||||
dom.normalizeTableColumns()
|
||||
new_c = dom.toxml()
|
||||
return new_c
|
||||
|
||||
def sxw2rml(sxw_file, xsl, output='.', save_pict=False):
|
||||
import libxslt
|
||||
import libxml2
|
||||
tool = PyOpenOffice(output, save_pict = save_pict)
|
||||
res = tool.unpackNormalize(sxw_file)
|
||||
styledoc = libxml2.parseDoc(xsl)
|
||||
style = libxslt.parseStylesheetDoc(styledoc)
|
||||
doc = libxml2.parseMemory(res,len(res))
|
||||
result = style.applyStylesheet(doc, None)
|
||||
|
||||
root = result.xpathEval("/document/stylesheet")
|
||||
if root:
|
||||
root=root[0]
|
||||
images = libxml2.newNode("images")
|
||||
for img in tool.images:
|
||||
node = libxml2.newNode('image')
|
||||
node.setProp('name', img)
|
||||
node.setContent( base64.encodestring(tool.images[img]))
|
||||
images.addChild(node)
|
||||
root.addNextSibling(images)
|
||||
try:
|
||||
xml = style.saveResultToString(result)
|
||||
return xml
|
||||
except:
|
||||
return result
|
||||
|
||||
if __name__ == "__main__":
|
||||
import optparse
|
||||
parser = optparse.OptionParser(
|
||||
version="Tiny Report v%s" % __version__,
|
||||
usage = 'tiny_sxw2rml.py [options] file.sxw')
|
||||
parser.add_option("-v", "--verbose", default=False, dest="verbose", help="enable basic debugging")
|
||||
parser.add_option("-o", "--output", dest="output", default='.', help="directory of image output")
|
||||
(opt, args) = parser.parse_args()
|
||||
if len(args) != 1:
|
||||
parser.error("incorrect number of arguments")
|
||||
|
||||
import sys
|
||||
import StringIO
|
||||
|
||||
fname = sys.argv[1]
|
||||
f = StringIO.StringIO(file(fname).read())
|
||||
|
||||
xsl = file(os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]), 'normalized_oo2rml.xsl')).read()
|
||||
result = sxw2rml(f, xsl, output=opt.output, save_pict=False)
|
||||
|
||||
print result
|
Loading…
Reference in New Issue