[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