[Erp5-report] r26306 - in /erp5/trunk/products/ERP5OOo: ./ tests/ tests/test_document/
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue Apr 7 03:39:56 CEST 2009
Author: tatuya
Date: Tue Apr 7 03:39:55 2009
New Revision: 26306
URL: http://svn.erp5.org?rev=26306&view=rev
Log:
* Clean up the code and the comments
* Append functions
- styles.xml support
- experimental FormBox support
- experimental ReportSection support
* Fix
the table column attribute name was wrong
Modified:
erp5/trunk/products/ERP5OOo/FormPrintout.py
erp5/trunk/products/ERP5OOo/tests/testFormPrintout.py
erp5/trunk/products/ERP5OOo/tests/test_document/Foo_001.odt
Modified: erp5/trunk/products/ERP5OOo/FormPrintout.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5OOo/FormPrintout.py?rev=26306&r1=26305&r2=26306&view=diff
==============================================================================
--- erp5/trunk/products/ERP5OOo/FormPrintout.py [utf8] (original)
+++ erp5/trunk/products/ERP5OOo/FormPrintout.py [utf8] Tue Apr 7 03:39:55 2009
@@ -29,7 +29,9 @@
from Products.PageTemplates.PageTemplateFile import PageTemplateFile
from Products.CMFCore.utils import _checkPermission, getToolByName
from Products.ERP5Type import PropertySheet, Permissions
-from Products.ERP5Form.ListBox import ListBox
+from Products.ERP5Form.ListBox import ListBox
+from Products.ERP5Form.FormBox import FormBox
+from Products.ERP5Form.ImageField import ImageField
from Products.ERP5OOo.OOoUtils import OOoBuilder
from Acquisition import Implicit
@@ -73,7 +75,7 @@
'Add and Edit' button is pressed.
Keyword arguments:
- id -- id of the object we just added
+ id -- the id of the object we just added
"""
if REQUEST is None:
return
@@ -90,7 +92,7 @@
The Form Printout enables to create a ODF document.
- The Form Printout receives a name of a ERP5 form, and a template name.
+ The Form Printout receives an ERP5 form name, and a template name.
Using their parameters, the Form Printout genereate a ODF document,
a form as a ODF document content, and a template as a document layout.
@@ -132,10 +134,6 @@
# default attributes
template = None
form_name = None
-
- def __str__(self): return self.index_html()
-
- def __len__(self): return 1
def __init__(self, id, title='', form_name='', template=''):
"""Initialize id, title, form_name, template.
@@ -209,16 +207,17 @@
NAME_SPACE_DICT = {'draw':'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0',
'table':'urn:oasis:names:tc:opendocument:xmlns:table:1.0',
'text':'urn:oasis:names:tc:opendocument:xmlns:text:1.0',
- 'office':'urn:oasis:names:tc:opendocument:xmlns:office:1.0'}
+ 'office':'urn:oasis:names:tc:opendocument:xmlns:office:1.0',
+ 'xlink':'http://www.w3.org/1999/xlink'}
class ODFStrategy(Implicit):
"""ODFStrategy creates a ODF Document. """
def render(self, extra_context={}):
- """Render a odt document, form as a content, template as a template.
+ """Render a odf document, form as a content, template as a template.
Keyword arguments:
- extra_context -- a dictionary, guess contains
+ extra_context -- a dictionary, expected:
'here' : where it call
'printout_template' : the template object, tipically a OOoTemplate
'container' : the object which has a form printout object
@@ -226,7 +225,6 @@
"""
here = extra_context['here']
if here is None:
- # This is a system error
raise ValueError, 'Can not create a ODF Document without a parent acquisition context'
form = extra_context['form']
if not extra_context.has_key('printout_template') or extra_context['printout_template'] is None:
@@ -234,12 +232,12 @@
odf_template = extra_context['printout_template']
- # First, render a OOoTemplate itself with its style
+ # First, render the Template if it has a pt_render method
ooo_document = None
if hasattr(odf_template, 'pt_render'):
ooo_document = odf_template.pt_render(here, extra_context=extra_context)
else:
- # File object, OOoBuilder directly support a file object
+ # File object can be a template
ooo_document = odf_template
# Create a new builder instance
@@ -247,8 +245,9 @@
# content.xml
ooo_builder = self._replace_content_xml(ooo_builder=ooo_builder, extra_context=extra_context)
- # styles.xml and meta.xml are not supported yet
- # ooo_builder = self._replace_styles_xml(ooo_builder=ooo_builder, extra_context=extra_context)
+ # styles.xml
+ ooo_builder = self._replace_styles_xml(ooo_builder=ooo_builder, extra_context=extra_context)
+ # meta.xml is not supported yet
# ooo_builder = self._replace_meta_xml(ooo_builder=ooo_builder, extra_context=extra_context)
# Update the META informations
@@ -258,25 +257,25 @@
return ooo
def _replace_content_xml(self, ooo_builder=None, extra_context=None):
- doc_xml = ooo_builder.extract('content.xml')
+ content_xml = ooo_builder.extract('content.xml')
# mapping ERP5Form to ODF
form = extra_context['form']
here = getattr(self, 'aq_parent', None)
- ordinaly_group_list = [group for group in form.get_groups() if group not in ['meta','style']]
- doc_xml = self._replace_xml_by_form(doc_xml=doc_xml,
- form=form,
- here=here,
- extra_context=extra_context,
- group_list=ordinaly_group_list)
+
+ content_element_tree = etree.XML(content_xml)
+ content_element_tree = self._replace_xml_by_form(element_tree=content_element_tree,
+ form=form,
+ here=here,
+ extra_context=extra_context)
# mapping ERP5Report report method to ODF
- doc_xml = self._replace_xml_by_report_section(doc_xml=doc_xml,
- extra_context=extra_context)
-
- if isinstance(doc_xml, unicode):
- doc_xml = doc_xml.encode('utf-8')
+ content_element_tree = self._replace_xml_by_report_section(element_tree=content_element_tree,
+ extra_context=extra_context)
+ content_xml = etree.tostring(content_element_tree)
+ if isinstance(content_xml, unicode):
+ content_xml = content_xml.encode('utf-8')
# Replace content.xml in master openoffice template
- ooo_builder.replace('content.xml', doc_xml)
+ ooo_builder.replace('content.xml', content_xml)
return ooo_builder
# this method not supported yet
@@ -284,19 +283,19 @@
"""
replacing styles.xml file in a ODF document
"""
- doc_xml = ooo_builder.extract('styles.xml')
+ styles_xml = ooo_builder.extract('styles.xml')
form = extra_context['form']
here = getattr(self, 'aq_parent', None)
- doc_xml = self._replace_xml_by_form(doc_xml=doc_xml,
- form=form,
- here=here,
- extra_context=extra_context,
- group_list=['styles'])
-
- if isinstance(doc_xml, unicode):
- doc_xml = doc_xml.encode('utf-8')
+ styles_element_tree = etree.XML(styles_xml)
+ styles_element_tree = self._replace_xml_by_form(element_tree=styles_element_tree,
+ form=form,
+ here=here,
+ extra_context=extra_context)
+ styles_xml = etree.tostring(styles_element_tree)
+ if isinstance(styles_xml, unicode):
+ styles_xml = styles_xml.encode('utf-8')
- ooo_builder.replace('styles.xml', doc_xml)
+ ooo_builder.replace('styles.xml', styles_xml)
return ooo_builder
# this method not implemented yet
@@ -304,54 +303,60 @@
"""
replacing meta.xml file in a ODF document
"""
- doc_xml = ooo_builder.extract('meta.xml')
+ meta_xml = ooo_builder.extract('meta.xml')
if isinstance(doc_xml, unicode):
- doc_xml = doc_xml.encode('utf-8')
+ meta_xml = meta_xml.encode('utf-8')
- ooo_builder.replace('meta.xml', doc_xml)
+ ooo_builder.replace('meta.xml', meta_xml)
return ooo_builder
- def _replace_xml_by_form(self, doc_xml=None, form=None, here=None,
- group_list=[], extra_context=None):
- field_list = [f for g in group_list for f in form.get_fields_in_group(g)]
- content = etree.XML(doc_xml)
+ def _replace_xml_by_form(self, element_tree=None, form=None, here=None,
+ extra_context=None, render_prefix=None):
+ field_list = form.get_fields()
REQUEST = get_request()
- for (count,field) in enumerate(field_list):
+ for (count, field) in enumerate(field_list):
if isinstance(field, ListBox):
- content = self._append_table_by_listbox(content=content,
- listbox=field,
- REQUEST=REQUEST)
+ element_tree = self._append_table_by_listbox(element_tree=element_tree,
+ listbox=field,
+ REQUEST=REQUEST,
+ render_prefix=render_prefix)
+ elif isinstance(field, FormBox):
+ sub_form = getattr(here, field.get_value('formbox_target_id'))
+ content = self._replace_xml_by_formbox(element_tree=element_tree,
+ field_id=field.id,
+ form = sub_form,
+ REQUEST=REQUEST)
+ #elif isinstance(field, ImageField):
+ # element_tree = self._replace_xml_by_image_field(element_tree=element_tree,
+ # image_field=field)
else:
- field_value = field.get_value('default')
- content = self._replace_node_via_reference(content=content,
- field_id=field.id,
- field_value=field_value)
- return etree.tostring(content)
-
- def _replace_node_via_reference(self, content=None, field_id=None, field_value=None):
+ element_tree = self._replace_node_via_reference(element_tree=element_tree,
+ field=field)
+ return element_tree
+
+ def _replace_node_via_reference(self, element_tree=None, field=None):
+ field_id = field.id
+ field_value = field.get_value('default')
# text:reference-mark text:name="invoice-date"
reference_xpath = '//text:reference-mark[@text:name="%s"]' % field_id
- reference_list = content.xpath(reference_xpath, namespaces=NAME_SPACE_DICT)
+ reference_list = element_tree.xpath(reference_xpath, namespaces=NAME_SPACE_DICT)
if len(reference_list) > 0:
node = reference_list[0].getparent()
- ## remove such a "bbb"
- ## <text:p>aaa<br/>bbb</text:p>
+ # remove such a "bbb": <text:p>aaa<br/>bbb</text:p>
for child in node.getchildren():
child.tail = ''
node.text = field_value
- return content
-
- def _replace_xml_by_report_section(self, doc_xml=None, extra_context=None):
+ return element_tree
+
+ def _replace_xml_by_report_section(self, element_tree=None, extra_context=None):
if not extra_context.has_key('report_method') or extra_context['report_method'] is None:
- return doc_xml
+ return element_tree
report_method = extra_context['report_method']
report_section_list = report_method()
portal_object = self.getPortalObject()
- content = etree.XML(doc_xml)
REQUEST = get_request()
request = extra_context.get('REQUEST', REQUEST)
-
render_prefix = None
for (index, report_item) in enumerate(report_section_list):
if index > 0:
@@ -360,31 +365,55 @@
here = report_item.getObject(portal_object)
form_id = report_item.getFormId()
form = getattr(here, form_id)
- for field in form.get_fields():
- if field.meta_type == 'ListBox':
- content = self._append_table_by_listbox(content=content,
- listbox=field,
- REQUEST=request,
- render_prefix=render_prefix)
+ element_tree = self._replace_xml_by_form(element_tree=element_tree,
+ form=form,
+ here=here,
+ extra_context=extra_context,
+ render_prefix=render_prefix)
report_item.popReport(portal_object, render_prefix = render_prefix)
-
- return etree.tostring(content)
+ return element_tree
+
+ def _replace_xml_by_formbox(self, element_tree=None, field_id=None, form=None, REQUEST=None):
+ draw_xpath = '//draw:frame[@draw:name="%s"]/draw:text-box/*' % field_id
+ text_list = element_tree.xpath(draw_xpath, namespaces=NAME_SPACE_DICT)
+ if len(text_list) == 0:
+ return element_tree
+ parent = text_list[0].getparent()
+ parent.clear()
+ # this form.__call__() possibly has a side effect,
+ # so must clear the 'here' context for listBox.get_value()
+ box = form(REQUEST=REQUEST);
+ REQUEST.set('here', None)
+ node = etree.XML(box)
+ # TODO style_copy
+ if node is not None:
+ for child in node.getchildren():
+ parent.append(child)
+ return element_tree
+
+ def _replace_xml_by_image_field(self, element_tree=None, image_field=None):
+ alt = image_field.get_value('description') or image_field.get_value('title')
+ image_xpath = '//draw:frame[@draw:name="%s"]/*' % image_field.id
+ image_list = element_tree.xpath(image_xpath, namespaces=NAME_SPACE_DICT)
+ if len(image_list) > 0:
+ image_list[0].set("{%s}href" % NAME_SPACE_DICT['xlink'], image_field.absolute_url())
+ return element_tree
def _append_table_by_listbox(self,
- content=None,
+ element_tree=None,
listbox=None,
REQUEST=None,
render_prefix=None):
table_id = listbox.id
table_xpath = '//table:table[@table:name="%s"]' % table_id
# this list should be one item list
- target_table_list = content.xpath(table_xpath, namespaces=NAME_SPACE_DICT)
+ target_table_list = element_tree.xpath(table_xpath, namespaces=NAME_SPACE_DICT)
if len(target_table_list) is 0:
- return content
+ return element_tree
target_table = target_table_list[0]
newtable = deepcopy(target_table)
- # <table:table-header-rows>
+
table_header_rows_xpath = '%s/table:table-header-rows' % table_xpath
table_row_xpath = '%s/table:table-row' % table_xpath
table_header_rows_list = newtable.xpath(table_header_rows_xpath, namespaces=NAME_SPACE_DICT)
@@ -392,7 +421,6 @@
# copy row styles from ODF Document
has_header_rows = len(table_header_rows_list) > 0
- LOG('FormPrintout has_header_rows', INFO, has_header_rows)
(row_top, row_middle, row_bottom) = self._copy_row_style(table_row_list,
has_header_rows=has_header_rows)
@@ -411,8 +439,8 @@
REQUEST=REQUEST,
render_prefix=render_prefix)
- # if ODF table has heder rows, does not update the header rows
- # if ODF table does not have header rows, insert the listbox title line
+ # if ODF table has header rows, does not update the header rows
+ # if does not have header rows, insert the listbox title line
is_top = True
for (index, listboxline) in enumerate(listboxline_list):
listbox_column_list = listboxline.getColumnItemList()
@@ -441,9 +469,8 @@
else:
# report section iteration
parent_paragraph.append(newtable)
- # TODO: it would be better append a paragraph or linebreak
- return content
+ return element_tree
def _copy_row_style(self, table_row_list=[], has_header_rows=False):
row_top = None
@@ -490,7 +517,7 @@
if listbox_column_index >= listbox_column_size:
break
value = listbox_column_list[listbox_column_index][1]
- # if value is None, remaining ODF orinal text
+ # if value is None, remaining the ODF original text
if value is not None:
self._set_column_value(column, value)
column_span = self._get_column_span_size(column)
@@ -502,7 +529,7 @@
def _set_column_value(self, column, value):
if value is None:
# to eliminate a default value, remove "office:*" attributes.
- # if remaining "office:*" attribetes, the column shows its default value,
+ # if remaining these attribetes, the column shows its default value,
# such as '0.0', '$0'
attrib = column.attrib
for key in attrib.keys():
@@ -512,11 +539,25 @@
column_value = unicode(str(value),'utf-8')
column.text = column_value
column_children = column.getchildren()
+ first_child = None
if len(column_children) > 0:
- column_children[0].text = column_value
+ first_child = deepcopy(column_children[0])
+ first_child.text = column_value
+ for child in column_children:
+ column.remove(child)
+ column.append(first_child)
if column_value != '':
- column.set("{%s}value" % NAME_SPACE_DICT['office'], column_value)
-
+ value_attribute = self._get_column_value_attribute(column)
+ if value_attribute is not None:
+ column.set(value_attribute, column_value)
+
+ def _get_column_value_attribute(self, column):
+ attrib = column.attrib
+ for key in attrib.keys():
+ if key.endswith("value"):
+ return key
+ return None
+
def _get_column_span_size(self, column=None):
span_attribute = "{%s}number-columns-spanned" % NAME_SPACE_DICT['table']
column_span = 1
@@ -538,7 +579,6 @@
return []
odf_cell_list = row_middle.findall("{%s}table-cell" % NAME_SPACE_DICT['table'])
column_span_list = []
- span_attribute = "{%s}number-columns-spanned" % NAME_SPACE_DICT['table']
for column in odf_cell_list:
column_span = self._get_column_span_size(column)
column_span_list.append(column_span)
Modified: erp5/trunk/products/ERP5OOo/tests/testFormPrintout.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5OOo/tests/testFormPrintout.py?rev=26306&r1=26305&r2=26306&view=diff
==============================================================================
--- erp5/trunk/products/ERP5OOo/tests/testFormPrintout.py [utf8] (original)
+++ erp5/trunk/products/ERP5OOo/tests/testFormPrintout.py [utf8] Tue Apr 7 03:39:55 2009
@@ -27,11 +27,8 @@
##############################################################################
import unittest
-from threading import Thread
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from AccessControl.SecurityManagement import newSecurityManager
-from Products.ERP5Form.Selection import Selection
-from Products.ERP5Form.SelectionTool import SelectionTool
from Products.ERP5OOo.OOoUtils import OOoBuilder
from zLOG import LOG , INFO
import os
@@ -270,7 +267,7 @@
self.assertFalse(content_xml.find("foo_title_2") > 0)
self.assertTrue(content_xml.find("foo_title_3") > 0)
- # 4. Irregular case: listbox have not a stat line, but table has a stat line
+ # 4. Irregular case: listbox has not a stat line, but table has a stat line
if test1._getOb("foo_2", None) is None:
test1.newContent("foo_2", portal_type='Foo Line')
get_transaction().commit()
@@ -300,7 +297,7 @@
self.assertFalse(content_xml.find("foo_title_3") > 0)
self.assertTrue(content_xml.find("foo_title_4") > 0)
- # 5. Normal case: the listobx of a form and the ODF table are same layout
+ # 5. Normal case: the listobx and the ODF table are same layout
foo_form.manage_renameObject('listbox', 'listbox2', REQUEST=request)
listbox2 = foo_form.listbox2
test1.foo_1.setTitle('foo_title_5')
Modified: erp5/trunk/products/ERP5OOo/tests/test_document/Foo_001.odt
URL: http://svn.erp5.org/erp5/trunk/products/ERP5OOo/tests/test_document/Foo_001.odt?rev=26306&r1=26305&r2=26306&view=diff
==============================================================================
Binary files - no diff available.
More information about the Erp5-report
mailing list