[Erp5-report] r35852 mayoro - /erp5/trunk/products/ERP5/Document/PDFTypeInformation.py

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Jun 1 12:43:44 CEST 2010


Author: mayoro
Date: Tue Jun  1 12:43:41 2010
New Revision: 35852

URL: http://svn.erp5.org?rev=35852&view=rev
Log:
Initial version of PDFTypeInformation to manage dynamic form based on pdf and sla files using flare cache

Modified:
    erp5/trunk/products/ERP5/Document/PDFTypeInformation.py

Modified: erp5/trunk/products/ERP5/Document/PDFTypeInformation.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/PDFTypeInformation.py?rev=35852&r1=35851&r2=35852&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/PDFTypeInformation.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/PDFTypeInformation.py [utf8] Tue Jun  1 12:43:41 2010
@@ -1,6 +1,8 @@
+# -*- coding: utf-8 -*-
 ##############################################################################
-#
 # Copyright (c) 2002-2007 Nexedi SARL and Contributors. All Rights Reserved.
+#                     Mayoro DIAGNE <mayoro at nexedi.com>
+#                     Guy Osvald <guy at nexedi.com>                                                               
 #
 # WARNING: This program as such is intended to be used by professional
 # programmers who take the whole responsability of assessing all potential
@@ -25,9 +27,383 @@
 #
 ##############################################################################
 
+import StringIO
 from AccessControl import ClassSecurityInfo
-from Products.ERP5Type import Permissions
+from Products.ERP5Type.Cache import CachingMethod
+from Products.ERP5Type import Permissions, PropertySheet
 from Products.ERP5Type.ERP5Type import ERP5TypeInformation
+from Products.ERP5Form.Form import ERP5Form
+from Products.ERP5Form.PDFForm import PDFForm
+from Products.ERP5Form.ScribusParser import ScribusParser
+from Products.ERP5Form.PDFParser import PDFParser
+from OFS.DTMLDocument import DTMLDocument
+from Products.ERP5Type.Utils import convertToUpperCase
+from Products.ERP5Type.Core.ActionInformation import CacheableAction
+
+import md5
+
+def getPropertiesCSSDict(parsed_scribus
+                      , page_gap
+                      , image_width
+                      , image_height
+                      , scribus_width
+                      , scribus_height
+                      , space_between_pages):
+  """
+  recover all CSS data relative to the current page_object (field)
+  and save these informations in the output dict
+  """ 
+  #image_width = 800
+  scaling_factor = min(float(image_width)/scribus_width,
+                       float(image_height)/scribus_height)
+  properties_css_dict = {}
+  properties_css_dict['head'] = {}
+  properties_css_dict['standard'] = {}
+  properties_css_dict['error'] = {}
+  properties_css_dict['err_d'] = {}
+  pages = range(len(parsed_scribus))
+  for page in pages:
+    page_content =  parsed_scribus[page]
+    page_id = "page_%s" % page
+    properties_css_page = {}
+    properties_css_pagediv = {}
+    properties_page = {}
+    properties_css_page['position'] = 'relative'
+    # creating image class for background
+    properties_css_background = {}
+    # making background id
+    background_id =  page_id + '_background'
+    # making page div id
+    pagediv_id =  page_id + ' div'
+    #getting properties
+    properties_css_background['position'] = 'absolute'
+    #creating corresponding page group to form
+    if page == 0:
+       # margin-top = 0 (first page)
+      properties_css_page['margin-top'] = "%spx" % (0)
+    else:
+      properties_css_page['margin-top'] = "%spx" % (40)
+
+    properties_css_page['margin']  = "0 auto 20px 0"
+    properties_css_page['border-color'] = "#CCCCCC"
+    properties_css_page['border-'] = "dotted none none"
+    properties_css_page['border-'] = "1px 0pt 0pt"
+    properties_css_page['border'] = "1px solid #999999"
+   
+    properties_css_pagediv['background'] = "transparent"
+    properties_css_pagediv['border'] = "0"
+
+    # set width and height on page block
+    properties_css_page['width'] = str (image_width) + 'px'
+    properties_css_page['height'] = str (image_height) + 'px'
+    properties_page['actual_width'] = scribus_width
+    properties_page['actual_height'] = scribus_height 
+    properties_css_background['height'] = str(image_height) + 'px'
+    properties_css_background['width'] = str (image_width) + 'px'
+    # adding properties dict to global dicts
+    properties_css_dict['head'][page_id] = properties_css_page
+    properties_css_dict['head'][background_id] = properties_css_background
+    properties_css_dict['head'][pagediv_id] = properties_css_pagediv
+    for field_name, properties_field in page_content:
+      properties_field['position_y'] = \
+          str(float(properties_field['position_y']) - \
+          (scribus_height + page_gap)* page)
+
+      # Processing object for CSS data
+      # declaring dict containing all css data
+      # _stand for general display
+      field_dict = {}
+      properties_css_object_stand = {}
+      # _error when an error occurs
+      properties_css_object_error = {}
+      # _err_d to diplay the text error
+      properties_css_object_err_d = {}
+      #defining global properties
+      properties_css_object_stand['position'] = 'absolute'
+      properties_css_object_error['position'] = 'absolute'
+      properties_css_object_err_d['position'] = 'absolute'
+      properties_css_object_stand['padding'] = '0px'
+      properties_css_object_error['padding'] = '0px'
+      properties_css_object_err_d['padding'] = '0px'
+      # getting field height
+      properties_css_object_stand['height'] = \
+          str(scaling_factor * float(properties_field['size_y'])) + 'px'
+      properties_css_object_error['height'] = \
+          str(scaling_factor * float(properties_field['size_y'])) + 'px'
+      # defining font-size from height - 2 (this value seems to have a good
+      # rendering on Mozilla and Konqueror)
+      # do not match for TextArea (as it is a multiline object)
+      type_list = ['TextAreaField', 'MultiListField', 'EditorField']
+      type_list +=  ['ListBox', 'ImageField', 'MatrixBox']
+      #if properties_field['type'] not in type_list:
+        #if float(properties_field['size_y']) > 8.0:
+          #properties_css_object_stand['font-size'] = \
+            #str((scaling_factor *float(properties_field['size_y']))-5.5 ) + 'px'
+          #properties_css_object_error['font-size'] = \
+            #str((scaling_factor *float(properties_field['size_y']))-5.5) + 'px'
+        #else:
+          #properties_css_object_stand['font-size'] = \
+            #str((scaling_factor *float(properties_field['size_y']))-3.5 ) + 'px'
+          #properties_css_object_error['font-size'] = \
+            #str((scaling_factor *float(properties_field['size_y']))-3.5) + 'px'
+      #else:
+        #properties_css_object_stand['font-size'] = '12px'
+        #properties_css_object_error['font-size'] = '12px'
+
+      # Use default font-size 12px for harmonization
+      properties_css_object_stand['font-size'] = '12px'
+      properties_css_object_error['font-size'] = '12px'
+
+      properties_css_object_err_d['margin-left'] = str(image_width +
+          space_between_pages ) + 'px'
+      properties_css_object_err_d['white-space'] = 'nowrap'
+      properties_css_object_stand['margin-top'] = \
+        str((scaling_factor *float(properties_field['position_y']))) + 'px'
+      properties_css_object_error['margin-top'] = \
+        str((scaling_factor *float(properties_field['position_y']))) + 'px'
+      properties_css_object_err_d['margin-top'] = \
+        str((scaling_factor *float(properties_field['position_y']))) + 'px'
+      # adding special text_color for text error
+      properties_css_object_err_d['color'] = 'rgb(255,0,0)'
+      # then getting additional properties
+      if properties_field['required'] ==1:
+        # field is required: using special color
+        # color is specified as light-blue when standard
+        # color = 'green' when error
+        properties_css_object_stand['background'] = 'rgb(236,245,220)'
+        properties_css_object_error['background'] = 'rgb(128,128,255)'
+      elif properties_field['type'] != 'TextAreaField':
+        properties_css_object_stand['background'] = '#F5F5DC'
+        properties_css_object_error['background'] = 'rgb(255,64,64)' #Previously,
+                                            #B9D9D4 - should become a parameter
+      else:
+        properties_css_object_stand['background'] = '#F5F5DC' # Previously,
+                                            #B9D9D4 - should become a parameter
+        properties_css_object_error['background'] = 'rgb(255,64,64)'
+
+      # add completed properties (in our case only the class rendering the text
+      # beside an error) to the return dict
+      properties_css_dict['err_d'][field_name] = properties_css_object_err_d
+      # the following variable take the number of field to render for this object
+      field_nb = 1
+      # now processing special rendering
+      if properties_field['rendering']=='single':
+        # single rendering (like StringField, TextArea, etc.).
+        # Do not need any special treatment
+        properties_css_object_stand['width'] = \
+          str(scaling_factor * float(properties_field['size_x'])) + 'px'
+        properties_css_object_error['width'] = \
+          str(scaling_factor * float(properties_field['size_x'])) + 'px'
+        properties_css_object_stand['margin-left'] = \
+          str((scaling_factor * float(properties_field['position_x']))) + 'px'
+        properties_css_object_error['margin-left'] = \
+          str((scaling_factor * float(properties_field['position_x']))) + 'px'
+        field_id = field_name + '_class'
+        # adding all these properties to the global dicts
+        properties_css_dict['standard'][field_id] = properties_css_object_stand
+        properties_css_dict['error'][field_id] = properties_css_object_error
+      else:
+        sub_field_dict = {}
+        field_dict = {}
+        if properties_field['type'] == 'RelationStringField':
+          # rendering a relationStringField, based on two input areas
+          # processing rendering of the two input fields. for that
+          # each has to be evaluated and the values will be saved in
+          # a dict
+          # uptading number of fields to render
+          field_nb = 2
+          #field_1 = field_name + '_class_1'
+          # processing main StringField
+          field_dict[1] = {}
+          field_dict[1]['width'] = \
+              str(scaling_factor*(float(properties_field['size_x']) / 2)) + 'px'
+          field_dict[1]['margin-left'] = \
+              str(scaling_factor*float(properties_field['position_x'])) + 'px'
+          # processing secondary input picture
+          field_dict[2] = {}
+          field_dict[2]['width'] = \
+              str(scaling_factor(float(properties_field['size_x']) /2)) + 'px'
+          field_dict[2]['margin-left'] = \
+                str(scaling_factor(float(properties_field['size_x']) /2  +\
+                float(properties_field['position_x']))) + 'px'
+        elif properties_field['type'] == 'DateTimeField':
+          # rendering DateTimeField, composed at least of three input
+          # areas, and their order can be changed
+          # getting the number of fields to render and their size unit
+          if properties_field['date_only'] == '0':
+            field_nb = 5
+            # defining counting unit for fields
+            # total = 6.1 units:
+            # 2 > year
+            # 1 > month
+            # 1 > day
+            # 0.1 > space between date and time
+            # 1 > hour
+            # 1 > minutes
+            width_part = int(float(properties_field['size_x']) / 6.1)
+          else: 
+            field_nb = 3
+            # same as before but without hours and minutes
+            width_part = int((float(properties_field['size_x']) / 4))
+          # defining global field rendering (for Date), ignoring for the moment
+          # the whole part about the time
+          # this following field refere to no existing field, it's use only 
+          # when editable property is unchecked (there is only one field 
+          # without _class_N but just _class, so, the 3 existing CSS selector 
+          # can't be applied, that the reason for this new one)
+          field_dict[0] = {}
+          field_dict[0]['width'] = \
+              str(scaling_factor*float(width_part*(field_nb+1))) + 'px'
+          field_dict[0]['margin-left'] = \
+              str(scaling_factor *float(properties_field['position_x'])) + 'px'
+
+          if properties_field['input_order'] in \
+                ['day/month/year', 'dmy', 'dmY', 'month/day/year', 'mdy', 'mdY']:
+            # specified input order. must be dd/mm/yyyy or mm/dd/yyyy (year is
+            # the last field).
+            # processing first field
+            field_dict[1] = {}
+            field_dict[1]['width'] = str(scaling_factor*float(width_part)) + \
+                'px'
+            field_dict[1]['margin-left'] = \
+                str(scaling_factor *float(properties_field['position_x'])) + 'px'
+            # processing second field
+            field_dict[2] = {}
+            field_dict[2]['width'] = str(scaling_factor*float(width_part)) + \
+                'px'
+            field_dict[2]['margin-left'] = \
+                str(scaling_factor *(float(properties_field['position_x']) + \
+                width_part)) + 'px'
+            # processing last field
+            field_dict[3] = {}
+            field_dict[3]['width'] = str(scaling_factor*float(width_part*2)) + \
+                'px'
+            field_dict[3]['margin-left'] = \
+                str(scaling_factor *(float(properties_field['position_x']) + \
+                width_part*2)) + 'px'
+          else:
+            # all other cases, including default one (year/month/day)
+            width_part = int(int(properties_field['size_x']) / 4)
+            # processing year field
+            field_dict[1] = {}
+            field_dict[1]['width'] = str(scaling_factor*float(width_part *2)) +\
+                'px'
+            field_dict[1]['margin-left'] = \
+                str(scaling_factor *float(properties_field['position_x'])) + 'px'
+            # processing second field (two digits only)
+            field_dict[2] = {}
+            field_dict[2]['width'] = str(scaling_factor*float(width_part)) + \
+                'px'
+            field_dict[2]['margin-left'] = \
+              str(scaling_factor *(float(properties_field['position_x']) + \
+              width_part*2)) + 'px'
+            # processing day field
+            field_dict[3] = {}
+            field_dict[3]['width'] = str(scaling_factor*float(width_part)) + \
+                'px'
+            field_dict[3]['margin-left'] = \
+              str(scaling_factor *(float(properties_field['position_x']) + \
+              width_part*3)) + 'px'
+          # rendering time if necessary
+          if properties_field['date_only'] == '0':
+            # date is specified
+            field_dict[4] = {}
+            field_dict[4]['width'] = str(width_part) + 'px'
+            field_dict[4]['margin-left'] = \
+                str(int(properties_field['position_x']) +\
+                int(properties_field['size_x']) - width_part*2) + 'px'
+            field_dict[5] = {}
+            field_dict[5]['width'] = str(width_part) + 'px'
+            field_dict[5]['margin-left'] = \
+                str(int(properties_field['position_x']) +\
+                int(properties_field['size_x']) - width_part) + 'px'
+
+        field_nb_range = field_nb + 1
+        field_range = range(field_nb_range)
+        for iterator in field_range:
+          # iterator take the field_id according to the field_nb
+          # ie (0..field_nb)
+          #iterator = it + 1
+          if iterator == 0:
+            class_name = field_name + '_class'
+          else:
+            class_name = field_name + '_class_' + str(iterator)
+          # managing standard class properties
+          properties_css_dict['standard'][class_name] = {}
+          for prop_id in properties_css_object_stand.keys():
+            # saving global class properties into final dict
+            properties_css_dict['standard'][class_name][prop_id] = \
+                properties_css_object_stand[prop_id]
+          for prop_id in field_dict[iterator].keys():
+            # then adding special field properties (usually width and position_x)
+            properties_css_dict['standard'][class_name][prop_id] = \
+                field_dict[iterator][prop_id]
+          # managing class error properties
+          properties_css_dict['error'][class_name] = {}
+          for prop_id in properties_css_object_error.keys():
+            properties_css_dict['error'][class_name][prop_id] = \
+                properties_css_object_error[prop_id]
+          for prop_id in field_dict[iterator].keys():
+            properties_css_dict['error'][class_name][prop_id] = \
+                field_dict[iterator][prop_id]
+
+  properties_css_page = {}
+  properties_css_page['position'] = 'relative'
+  properties_css_page['margin-top'] = "%spx" % str(space_between_pages)
+  properties_css_dict['head']['page_end'] = properties_css_page
+  return properties_css_dict
+
+def generateCSSOutputContent(properties_css_dict):
+  """
+  return a string containing the whole content of the CSS output
+  from properties_css_dict
+  """
+  form_css_content =  "/*-- special css form generated through ScribusUtils"\
+      "module     --*/\n"
+  form_css_content += "/*-- to have a graphic rendering with 'form_html' "\
+      "page template --*/\n\n"
+  form_css_content += "/* head : classes declared for general purpose */\n"
+  # iterating classes in document's head
+  for class_name in properties_css_dict['head'].keys():
+    # getting class properties_dict
+    class_properties = properties_css_dict['head'][class_name]
+    # joining exerything
+    output_string = "." + str(class_name) + " {" \
+                    + "; ".join(["%s:%s" % (id, val) for id, 
+                      val in class_properties.items()]) \
+                    + "}"
+    # adding current line to css_content_object
+    form_css_content += output_string + "\n"
+  form_css_content += "\n/* standard field classes */ \n"
+  # adding standard classes
+  for class_name in properties_css_dict['standard'].keys():
+    class_properties = properties_css_dict['standard'][class_name]
+    output_string = "." + str(class_name) + " {" \
+                    + "; ".join(["%s:%s" % (id, val) for id, 
+                      val in class_properties.items()]) \
+                    + "}"
+    form_css_content += output_string + "\n"
+  form_css_content += "\n/* error field classes */\n"
+  # adding error classes
+  for class_name in properties_css_dict['error'].keys():
+    class_properties = properties_css_dict['error'][class_name]
+    output_string = "." + str(class_name) + "_error {" \
+                    + "; ".join(["%s:%s" % (id, val) for id,
+                    val in class_properties.items()]) \
+                    + "}"
+    form_css_content += output_string + "\n"
+  form_css_content += "\n/* text_error field classes */ \n"
+  # adding field error classes
+  for class_name in properties_css_dict['err_d'].keys():
+    class_properties = properties_css_dict['err_d'][class_name]
+    output_string = "." + str(class_name) + "_error_display {" \
+                    + "; ".join(["%s:%s" % (id, val) for id,
+                    val in class_properties.items()]) \
+                    + "}"
+    form_css_content += output_string + "\n"
+  # return final String
+  return form_css_content
+
 
 class PDFTypeInformation(ERP5TypeInformation):
   """
@@ -40,7 +416,369 @@
   # CMF Type Definition
   meta_type = 'ERP5 PDF Type Information'
   portal_type = 'PDF Type'
+  isPortalContent = 1
+  isRADContent = 1
+
+  property_sheets = ( PropertySheet.PDFType, )
 
   # Declarative security
   security = ClassSecurityInfo()
   security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+  security.declareProtected(Permissions.View, 'renderForm')
+  def renderForm(self, context):
+    """
+    """
+    form = self.getERP5Form()
+    return form.__of__(context)()
+
+  security.declareProtected(Permissions.View, 'renderPDFForm')
+  def renderPDFForm(self, context):
+    """
+    """
+    form = self.getPDFForm()
+    return form.__of__(context)()
+
+  security.declareProtected(Permissions.View, 'renderFormImage')
+  def renderFormImage(self, REQUEST, RESPONSE, page):
+    """
+    """
+    return self.getERP5FormImage(page).index_html(REQUEST, RESPONSE)
+
+  security.declareProtected(Permissions.View, 'renderFormCSS')
+  def renderFormCSS(self):
+    """
+    """
+    return self.getERP5FormCSS()
+
+  def _getParsedScribusFile(self):
+    """
+      Returns a reusable data structure which can 
+      be used to generate ERP5 Form, ERP5 Form CSS,
+      PDF Form, etc.
+    """
+    scribus_form = self.getDefaultScribusFormValue()
+    if scribus_form is None:
+      return
+
+    def generateParsedScribus():
+      import_scribus_file = StringIO.StringIO(scribus_form.getData())
+      scribus_parser = ScribusParser(import_scribus_file)
+      import_scribus_file.close()
+      return scribus_parser.getERP5PropertyDict()
+    generateParsedScribus = CachingMethod(generateParsedScribus, 
+                                        ('PDFTypeInformation_generateParsedScribus',
+                                        md5.new(scribus_form.getData()).digest()),
+                                        cache_factory='dms_cache_factory')
+    return generateParsedScribus()
+
+  def getERP5Form(self):
+    """
+      Returns an ERP5 Form instance (stored in RAM)
+    """
+    if self.getDefaultScribusFormValue() is None:
+      return 
+
+    def generateERP5Form():
+      form_name = "view"
+      form = ERP5Form(form_name, self.getId())
+      parsed_scribus = self._getParsedScribusFile()
+      pages = range(len(parsed_scribus))
+      #get the context for default values
+      context = None
+      context_parent = self.aq_parent
+      if context_parent is not None:
+        context = context_parent.aq_parent
+      for page in pages:
+        page_content =  parsed_scribus[page]
+        group_id = page_id = "page_%s" % page
+        if page != 0:
+          group = form.add_group(group_id)
+        for field_name, fields_values in page_content:
+          field_id = field_name
+          field_title = fields_values["title"]
+          field_order = fields_values["order"]
+          field_erp5_order = fields_values["nb"]
+          field_type = fields_values["type"]
+          field_required = fields_values["required"]
+          field_editable = fields_values["editable"]
+          field_rendering = fields_values["rendering"]
+          field_size_x = fields_values["size_x"]
+          field_size_y = fields_values["size_y"]
+          field_position_x = fields_values["position_x"]
+          field_position_y = fields_values["position_y"]
+          old_group='left'
+          # creating new field in form
+          if field_type in ['ListField', 'MultiListField']:
+            field = form.manage_addField(field_id,
+                                field_title,
+                                'ProxyField')
+            field = form[field_name]
+            field.values['form_id'] = 'Base_viewFieldLibrary'
+            if field_type == 'ListField':
+              field.values['field_id'] = 'my_list_field'
+            else:
+              field.values['field_id'] = 'my_multi_list_field'
+            # ne pas déléguer les propriétés items et default  
+            field.delegated_list += ('items', 'default') 
+            field.manage_tales_xmlrpc({"items":
+              "python: here.EGov_getCategoryChildItemListByFieldName('%s')"\
+              % field_id})
+            field.manage_tales_xmlrpc({"default":
+              "python: here.getProperty('%s')" % field_id[3:]})
+          elif field_type == 'DateTimeField':
+            field = form.manage_addField(field_id,
+                                field_title,
+                                'ProxyField')
+            field = form[field_name]
+            field.values['form_id'] = 'Base_viewFieldLibrary'
+            field.values['field_id'] = 'my_date'
+            field.delegated_list += ('default',)  
+            field.manage_tales_xmlrpc({"default":
+              "python: here.getProperty('%s')" % field_id[3:]})
+          else:
+            field = form.manage_addField(field_id,
+                                field_title,
+                                field_type)
+
+          field = form[field_name]
+
+          field.values['required'] = field_required
+          field.values['editable'] = field_editable
+         
+          if page != 0:
+            # move fields to destination group
+            form.move_field_group(field_id,
+                                  old_group,
+                                  group_id)
+
+
+      default_groups = ['right', 'center', 'bottom', 'hidden']
+      old_group='left'
+      group_id = 'page_0'
+      form.rename_group(old_group, group_id)
+      # remove all other groups:
+      for existing_group in default_groups:
+        form.remove_group(existing_group)
+      # updating form settings
+      # building dict containing (property, value)
+      values = {}
+      values['title'] = self.getId()
+      values['row_length'] = 4
+      values['name'] = form_name
+      values['pt'] = "form_render_PDFeForm"
+      values['action'] = "PDFDocument_edit"
+      values['update_action'] = ""
+      values['method'] = 'POST'
+      values['enctype'] = 'multipart/form-data'
+      values['encoding'] = "UTF-8"
+      values['stored_encoding'] = 'UTF-8'
+      values['unicode_mode'] = 0
+      #values['getBackgroundUrl'] = self.getBackgroundUrl(page)
+      #values['getCSSUrl'] = self.getCSSUrl()
+
+      values['getBackgroundUrl'] = lambda page: \
+        'portal_types/%s/renderFormImage?page=%s' % (self.getId(), page)
+      values['getCSSUrl'] = lambda: 'portal_types/%s/renderFormCSS' % self.getId()
+
+      # using the dict declared just above to set the attributes
+      for key, value in values.items():
+        setattr(form, key, value)
+      return form
+    #generateERP5Form = CachingMethod(generateERP5Form, 
+    #                                ('PDFTypeInformation_generateERP5Form',
+    #                                md5.new(self.getDefaultScribusFormValue().getData()).digest()),
+    #                                cache_factory='erp5_ui_long')
+    return generateERP5Form().__of__(self)
+
+  # XXX criticize ERP5.Document.Image
+  #     (we are forced to use xlarge preference)
+  def getWidth(self):
+    portal_preferences = self.getPortalObject().portal_preferences
+    return portal_preferences.getPreferredXlargeImageWidth()
+
+  def getHeight(self):
+    portal_preferences = self.getPortalObject().portal_preferences
+    return portal_preferences.getPreferredXlargeImageHeight()
+
+
+  def getERP5FormCSS(self):
+    """
+      Returns a CSS file containing all layout instructions
+    """
+    if self.getDefaultScribusFormValue() is None:
+      return
+    def generateERP5FormCSS():    
+      parsed_scribus = self._getParsedScribusFile()
+      import_pdf_file = StringIO.StringIO(self.getDefaultPdfFormValue().getData())
+      pdf_parser = PDFParser(import_pdf_file)
+      import_scribus_file = StringIO.StringIO(self.getDefaultScribusFormValue().getData())
+      scribus_parser = ScribusParser(import_scribus_file)
+      page_gap = scribus_parser.getPageGap()
+      scribus_width = scribus_parser.getPageWidth()
+      scribus_height = scribus_parser.getPageHeight()
+      space_between_pages = 20 # XXX - hardcoded
+      image0 = self.getERP5FormImage(0)
+      properties_css_dict=getPropertiesCSSDict(parsed_scribus,
+                                              page_gap,
+                                              image0.getWidth(),
+                                              image0.getHeight(),
+                                              scribus_width,
+                                              scribus_height,
+                                              space_between_pages)
+      # declaring object that holds the CSS data
+      css_file_name = "%s_css.css" % self.getId().replace(' ','')
+      css_file_content = generateCSSOutputContent(properties_css_dict)
+      css_file = DTMLDocument(css_file_content, __name__ = css_file_name) 
+      import_scribus_file.close()
+      import_pdf_file.close()
+      return css_file
+
+    generateERP5FormCSS = CachingMethod(generateERP5FormCSS, 
+                                        ('PDFTypeInformation_generateERP5FormCSS',
+                                        md5.new(self.getDefaultScribusFormValue().getData()).digest()),
+                                        cache_factory='dms_cache_factory')
+    self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/css')
+    return generateERP5FormCSS()
+
+
+  def getERP5FormImage(self, page):
+    """
+      Returns the background image for a given page
+    """
+    from Products.ERP5Type.Document import newTempImage
+    import_pdf_file = self.getDefaultPdfFormValue()
+    #depend on preferences, best xlargeheight = 1131
+    mime, image_data = import_pdf_file.convert(format = 'jpg', 
+                                                frame = page, 
+                                                resolution = self.getResolution(),
+                                                quality = 600,
+                                                display = 'xlarge')
+    if image_data is None:
+      return
+    page_image = newTempImage(self, "page_%s" % page)
+    page_image.setData(image_data)
+    self.REQUEST.RESPONSE.setHeader('Content-Type', mime)
+    return page_image
+
+  def getPDFForm(self):
+    """
+      Returns an PDF Form instance (stored in RAM)
+    """
+    if self.getDefaultScribusFormValue() is None:
+      return
+    portal_type_name = self.getId().replace(' ','')
+    pdf_form_name ='%s_view%sAsPdf' % (portal_type_name, portal_type_name)
+    pdf_file = StringIO.StringIO(self.getDefaultPdfFormValue().getData())
+    pdf_form = PDFForm(pdf_form_name, portal_type_name, pdf_file)    
+    pdf_form.manage_upload(pdf_file)
+    import_scribus_file = StringIO.StringIO(self.getDefaultScribusFormValue().getData())
+    scribus_parser = ScribusParser(import_scribus_file)    
+    erp5_properties = scribus_parser.getERP5PropertyDict()    
+    def_usePropertySheet = 0
+    my_prefix = 'my_'
+    prefix_len = len(my_prefix)
+    pages = range(len(erp5_properties))
+    for page in pages: 
+      page_content =  erp5_properties[page]
+      for cell_name, field_dict in page_content:
+      # current object is PDF Form
+        if cell_name[:prefix_len] == my_prefix:
+          cell_process_name_list = []
+          suffix = cell_name[prefix_len:].split('_')[-1]
+          # If properties field are filled in scribus, get Type form
+          # global_properties. Else, guess Type by suffix id (eg: List, Date,...)
+          list_field_type_list = ('ListField', 'MultiListField', 'LinesField',)
+          date_field_type_list = ('DateTimeField',)
+          suffix_mapping = {'List' : list_field_type_list,
+                            'Date' : date_field_type_list}
+          field_type = field_dict.get('erp_type', suffix_mapping.get(suffix, [''])[0])
+          if def_usePropertySheet:
+            # generating PropertySheet and Document, no need to use them to
+            # get field data
+            if field_type in list_field_type_list:
+              TALES = "python: %s " % ', '.join(
+              "here.get%s()" % convertToUpperCase(cell_name[prefix_len:]))
+            elif field_type in date_field_type_list:
+              attributes_dict = field_dict['attributes']
+              # assign the property input_order
+              input_order = attributes_dict['input_order']
+              input_order = input_order.replace('y', 'Y')
+              # make the Tales according to the cases
+              date_pattern = '/'.join(['%%%s' % s for s in list(input_order)])
+              if not(attributes_dict['date_only']):
+                date_pattern += ' %H:%M'
+              TALES = "python: here.get%s() is not None and here.get%s().strftime('%s') or ''"\
+                % (convertToUpperCase(cell_name[prefix_len:]),
+                  convertToUpperCase(cell_name[prefix_len:]),
+                  date_pattern)
+            else:
+              TALES = "python: here.get%s()" %\
+                                convertToUpperCase(cell_name[prefix_len:])
+          else:
+            if field_type in list_field_type_list:
+              TALES = "python: %s" % ', '.join(
+                    "here.getProperty('%s')" % cell_name[prefix_len:])
+            elif field_type in date_field_type_list:
+              attributes_dict = field_dict['attributes']
+              # assign the property input_order
+              input_order = attributes_dict['input_order']
+              input_order = input_order.replace('y', 'Y')
+              # make the Tales according to the cases
+              date_pattern = '/'.join(['%%%s' % s for s in list(input_order)])
+              if not(attributes_dict['date_only']):
+                date_pattern += ' %H:%M'
+              TALES = "python: here.getProperty('%s') is not None and here.getProperty('%s').strftime('%s') or ''"\
+                    % (cell_name[prefix_len:],
+                        cell_name[prefix_len:],
+                        date_pattern)
+            else:
+              TALES = "python: here.getProperty('%s')" % cell_name[prefix_len:]
+          pdf_form.setCellTALES(cell_name, TALES)
+    import_scribus_file.close() 
+    pdf_file.close()
+    self.REQUEST.RESPONSE.setHeader('Content-Type', 'application/pdf')
+    return pdf_form   
+
+
+  def getCacheableActionList(self):
+    portal_type_name = self.getId().replace(' ','')
+    pdf_form_name ='%s_view%sAsPdf' % (portal_type_name, portal_type_name)
+    action_list = ERP5TypeInformation.getCacheableActionList(self)
+    return list(action_list) + [
+      CacheableAction(id='view',
+                      name='Form',
+                      description='',
+                      category='object_view',
+                      priority=1.1,
+                      icon=None,
+                      action='string:${object_url}/PDFType_viewDefaultForm',
+                      condition=None,
+                      permission_list=['View']),
+      CacheableAction(id=pdf_form_name,
+                      name='PDF Form',
+                      description='',
+                      category='object_print',
+                      priority=3.0,
+                      icon=None,
+                      action='string:${object_url}/PDFType_viewAsPdf',
+                      condition=None,
+                      permission_list=['View']),
+    ]
+
+  def updatePropertySheetDefinitionDict(self, definition_dict, **kw):
+    if self.getDefaultScribusFormValue() is None:
+      return
+    if '_properties' in definition_dict:
+      parsed_scribus = self._getParsedScribusFile()
+      for page_content in parsed_scribus.itervalues():
+        for field_name, fields_values in page_content:
+          field_id = field_name
+          field_type = fields_values["data_type"]
+          definition_dict['_properties'].append({'id':field_name[3:],
+                                                 'type':field_type,
+                                                 'mode':'w'})
+    ERP5TypeInformation.updatePropertySheetDefinitionDict(self, definition_dict)
+
+    
+




More information about the Erp5-report mailing list