[Erp5-report] r31496 fabien - /erp5/trunk/products/ERP5Form/ImageField.py

nobody at svn.erp5.org nobody at svn.erp5.org
Mon Dec 28 16:46:13 CET 2009


Author: fabien
Date: Mon Dec 28 16:46:12 2009
New Revision: 31496

URL: http://svn.erp5.org?rev=31496&view=rev
Log:
- change the way the image is replaced : use the image "as she is display", so
  if the image is display as a thumbnail, the image will be added in the odg
  document as thumbnail size/quality
- _replaceImage method is not required anymore, remove it
- update methods signatures to be consistent with other render_*
- if there is some height and width in the node attribute (because of
  attr_dict), try to make the image smaller or equal to this dimentions, and
  keep proportion

Modified:
    erp5/trunk/products/ERP5Form/ImageField.py

Modified: erp5/trunk/products/ERP5Form/ImageField.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5Form/ImageField.py?rev=31496&r1=31495&r2=31496&view=diff
==============================================================================
--- erp5/trunk/products/ERP5Form/ImageField.py [utf8] (original)
+++ erp5/trunk/products/ERP5Form/ImageField.py [utf8] Mon Dec 28 16:46:12 2009
@@ -32,13 +32,20 @@
 from lxml.etree import Element
 from Acquisition import aq_base
 from lxml import etree
+from decimal import Decimal
+import re
 
 DRAW_URI = 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0'
 TEXT_URI = 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'
+XLINK_URI = 'http://www.w3.org/1999/xlink'
+SVG_URI = 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0'
+
 
 NSMAP = {
           'draw': DRAW_URI,
           'text': TEXT_URI,
+          'xlink': XLINK_URI,
+          'svg': SVG_URI
         }
 
 class ImageFieldWidget(Widget.TextWidget):
@@ -102,44 +109,8 @@
             extra=extra,
         )
 
-    def _replaceImage(self, image_frame_node, ooo_builder, image_field,
-        printout, REQUEST, attr_dict):
-      """
-      Replace the image in an odg file using an ERP5Form image field.
-      return True if the image have been found, else return False
-      """
-      image_node = image_frame_node.getchildren()[0]
-      path = '/'.join(REQUEST.physicalPathFromURL(image_field.get_value('default')))
-      if path in (None, ''):
-        # not possible to add image, remove the existing one
-        image_frame_node = image_node.getparent()
-        image_frame_node.remove(image_node)
-        return False
-      path = path.encode()
-      image_object = image_field.getPortalObject().restrictedTraverse(path)
-      image_parameter_dict = {
-                    'display': image_field.get_value('image_display'),
-                    'format': image_field.get_value('image_format')
-                   }
-      picture_type, image_data = image_object.convert(**image_parameter_dict)
-      if image_data is None:
-        # not possible to add image, remove the existing one
-        image_frame_node = image_node.getparent()
-        image_frame_node.remove(image_node)
-        return False
-      picture_path = printout._createOdfUniqueFileName(path=path,
-          picture_type=picture_type)
-      ooo_builder.addFileEntry(picture_path, media_type=picture_type, content=image_data)
-      width, height = printout._getPictureSize(image_object, image_node)
-      image_node.set('{%s}href' % image_node.nsmap['xlink'], picture_path)
-      image_frame_node.set('{%s}width' % image_node.nsmap['svg'], width)
-      image_frame_node.set('{%s}height' % image_node.nsmap['svg'], height)
-      attr_dict.setdefault(image_node.tag, {}).update(image_node.attrib)
-      attr_dict.setdefault(image_frame_node.tag, {}).update(image_frame_node.attrib)
-      return True
-
-    def render_odg(self, field, as_string, local_name, target_node, printout,
-        REQUEST, ooo_builder, attr_dict=None):
+    def render_odg(self, field, value, as_string, ooo_builder, REQUEST,
+        render_prefix, attr_dict):
       """
         return an image xml node rendered in odg format
         if as_string is True (default) the returned value is a string (xml
@@ -147,34 +118,88 @@
         object.
         attr_dict can be used for additional parameters (like style).
       """
-      # replace the image in the odg document
-      if not self._replaceImage(target_node, ooo_builder, field, printout,
-          REQUEST, attr_dict):
-        # if image is not found, return None
-        return None
-
       if attr_dict is None:
         attr_dict = {}
-
+      draw_frame_node = None
+      if value in ('', None):
+        return None
+      path = '/'.join(REQUEST.physicalPathFromURL(value))
+      path = path.encode()
+      image_object = field.getPortalObject().restrictedTraverse(path)
+      display = field.get_value('image_display')
+      format = field.get_value('image_format')
+      image_parameter_dict = { 'display': display,
+                               'format':format}
+      # convert the image using fields parameters. In this way, if an image
+      # is displayed in the form as a thumbnail, it will be added in the odg
+      # document as thumbnail size/quality
+      content_type, image_data = image_object.convert(**image_parameter_dict)
+      if image_data is None:
+        return draw_frame_node
+
+      format = content_type.split('/')[-1]
+      # add the image to the odg document
+      picture_path = ooo_builder.addImage(image=image_data, format=format)
+
+      # create the xml nodes related to the image
       draw_frame_tag_name = '{%s}%s' % (DRAW_URI, 'frame')
       draw_frame_node = Element(draw_frame_tag_name, nsmap=NSMAP)
-      draw_frame_node.attrib.update(attr_dict.get(draw_frame_tag_name, {}))
-
-      draw_image_tag_name = '{%s}%s' % (DRAW_URI, 'image')
-      draw_image_node = Element(draw_image_tag_name, nsmap=NSMAP)
-      draw_image_node.attrib.update(attr_dict.get(draw_image_tag_name, {}))
-
-      text_p_tag_name = '{%s}%s' % (TEXT_URI, local_name)
-      text_p_node = Element(text_p_tag_name, nsmap=NSMAP)
-      text_p_node.attrib.update(attr_dict.get(text_p_tag_name, {}))
-
-      draw_image_node.append(text_p_node)
-      draw_frame_node.append(draw_image_node)
-
+      draw_frame_node.attrib.update(attr_dict.get(draw_frame_tag_name,
+        {}).pop(0))
+
+      # set the size of the image
+      if display is not None:
+        height, width = image_object.getSizeFromImageDisplay(display)
+        if draw_frame_node.attrib.get('{%s}width' % SVG_URI, {}) != {} and \
+        draw_frame_node.attrib.get('{%s}height' % SVG_URI, {}) != {}:
+          # if a size already exist from attr_dict, try to resize the image to
+          # fit this size (image should not be biger than size from attr_dict)
+          # devide the value by 20 to have cm instead of px
+          width, height = self._getPictureSize(width/20., height/20.,
+              target_width=draw_frame_node.attrib.get('{%s}width' % SVG_URI, {}),
+              target_height=draw_frame_node.attrib.get('{%s}height' % SVG_URI, {}))
+
+        draw_frame_node.set('{%s}width' % SVG_URI, str(width))
+        draw_frame_node.set('{%s}height' % SVG_URI, str(height))
+
+      image_tag_name = '{%s}%s' % (DRAW_URI, 'image')
+      image_node = Element(image_tag_name, nsmap=NSMAP)
+      image_node.attrib.update(attr_dict.get(image_tag_name, {}).pop())
+      image_node.set('{%s}href' % XLINK_URI, picture_path)
+
+      draw_frame_node.append(image_node)
       if as_string:
         return etree.tostring(draw_frame_node)
       return draw_frame_node
 
+    def _getPictureSize(self, picture_width, picture_height, target_width,
+        target_height):
+      # if not match causes exception
+      width_tuple = re.match("(\d[\d\.]*)(.*)", target_width).groups()
+      height_tuple = re.match("(\d[\d\.]*)(.*)", target_height).groups()
+      unit = width_tuple[1]
+      w = float(width_tuple[0])
+      h = float(height_tuple[0])
+      aspect_ratio = 1
+      try: # try image properties
+        aspect_ratio = picture_width / picture_height
+      except (TypeError, ZeroDivisionError):
+        try: # try ERP5.Document.Image API
+          height = picture_height
+          if height:
+            aspect_ratio = picture_width / height
+        except AttributeError: # fallback to Photo API
+          height = float(picture_height)
+          if height:
+            aspect_ratio = picture_width / height
+      resize_w = h * aspect_ratio
+      resize_h = w / aspect_ratio
+      if resize_w < w:
+        w = resize_w
+      elif resize_h < h:
+        h = resize_h
+      return (str(w) + unit, str(h) + unit)
+
 ImageFieldWidgetInstance = ImageFieldWidget()
 ImageFieldValidatorInstance = Validator.StringValidator()
 




More information about the Erp5-report mailing list