[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