Commit 17c9a357 authored by Romain Courteaud's avatar Romain Courteaud

Bug fix: do not write in the ZODB anymore while rendering the field.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@6153 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent a4bb1b3d
############################################################################## ##############################################################################
# #
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved. # Copyright (c) 2005, 2006 Nexedi SARL and Contributors. All Rights Reserved.
# Romain Courteaud <romain@nexedi.com> # Romain Courteaud <romain@nexedi.com>
# #
# WARNING: This program as such is intended to be used by professional # WARNING: This program as such is intended to be used by professional
...@@ -30,17 +30,10 @@ from Products.Formulator import Widget, Validator ...@@ -30,17 +30,10 @@ from Products.Formulator import Widget, Validator
from Products.Formulator.Field import ZMIField from Products.Formulator.Field import ZMIField
from Products.Formulator import StandardFields from Products.Formulator import StandardFields
from Products.Formulator.DummyField import fields from Products.Formulator.DummyField import fields
from Products.ERP5Type.Utils import convertToUpperCase
from Products.CMFCore.utils import getToolByName
from Globals import get_request
from Products.PythonScripts.Utility import allow_class from Products.PythonScripts.Utility import allow_class
import string
from zLOG import LOG from zLOG import LOG
from Products.Formulator.Widget import ItemsWidget
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Form import BasicForm
from Products.Formulator.Errors import ValidationError from Products.Formulator.Errors import ValidationError
class ParallelListWidget(Widget.MultiListWidget): class ParallelListWidget(Widget.MultiListWidget):
...@@ -78,143 +71,193 @@ class ParallelListWidget(Widget.MultiListWidget): ...@@ -78,143 +71,193 @@ class ParallelListWidget(Widget.MultiListWidget):
"The method to call to hash items list."), "The method to call to hash items list."),
required=0) required=0)
def _generateSubForm(self, field, key, value, REQUEST): def __init__(self):
item_list = filter(lambda x: x not in [ ('',''), ['',''] ], """
field.get_value('items')) Generate some subwidget used for rendering.
"""
value_list = value self.sub_widget = {
if type(value_list) not in (type([]), type(())): 'ListField': Widget.ListWidgetInstance,
value_list = [value_list] 'MultiListField': Widget.MultiListWidgetInstance,
empty_sub_field_property_dict = {
'key': 'default',
'title': '',
'required': 0,
'field_type': 'MultiListField',
'item_list': [],
'value': [],
'is_right_display': 0,
'size': 5
} }
hash_list = []
hash_script_id = field.get_value('hash_script_id')
if hash_script_id not in [None, '']:
here = REQUEST['here']
script = getattr(here, hash_script_id)
script_hash_list = script(
item_list,
value_list,
default_sub_field_property_dict=empty_sub_field_property_dict,
is_right_display=0)
hash_list.extend(script_hash_list)
else:
# No hash_script founded, generate a little hash_script
# to display only a MultiListField
default_sub_field_property_dict = empty_sub_field_property_dict.copy()
default_sub_field_property_dict['item_list'] = item_list
default_sub_field_property_dict['value'] = value_list
default_sub_field_property_dict['title'] = self.title
hash_list.append(default_sub_field_property_dict)
# XXX Regenerate fields each time....
field.sub_form = create_aggregated_list_sub_form(hash_list)
return hash_list
def render(self, field, key, value, REQUEST): def render(self, field, key, value, REQUEST):
hash_list = self._generateSubForm(field, key, value, REQUEST) hash_list = field._generateSubForm(value, REQUEST)
# Call render on each sub field # Call render on each sub field
sub_field_render_list = [] sub_field_render_list = []
for sub_field_property_dict in hash_list: for sub_field_property_dict in hash_list:
sub_field_render_list.append(field.render_sub_field( sub_field_render_list.append(self.render_sub_field(
sub_field_property_dict['key'], field, key,
sub_field_property_dict['value'], REQUEST, sub_field_property_dict['value'], REQUEST,
key=key)) sub_field_property_dict))
# Aggregate all renders # Aggregate all renders
html_string = string.join(sub_field_render_list, html_string = field.get_value('view_separator').\
field.get_value('view_separator')) join(sub_field_render_list)
return html_string return html_string
def render_htmlgrid(self, field, key, value, REQUEST): def render_htmlgrid(self, field, key, value, REQUEST):
hash_list = self._generateSubForm(field, key, value, REQUEST) hash_list = field._generateSubForm(value, REQUEST)
# Call render on each sub field # Call render on each sub field
sub_field_render_list = [] sub_field_render_list = []
for sub_field_property_dict in hash_list: for sub_field_property_dict in hash_list:
sub_field_render_list.append((sub_field_property_dict['title'], sub_field_render_list.append((
field.render_sub_field( sub_field_property_dict['title'],
sub_field_property_dict['key'], self.render_sub_field(
sub_field_property_dict['value'], REQUEST, field, key,
key=key))) sub_field_property_dict['value'], REQUEST,
sub_field_property_dict)))
return sub_field_render_list return sub_field_render_list
def render_sub_field(self, field, key, value, REQUEST,
sub_field_property_dict):
"""
Render dynamically a subfield
"""
REQUEST.set('_v_plf_title', sub_field_property_dict['title'])
REQUEST.set('_v_plf_required', sub_field_property_dict['required'])
REQUEST.set('_v_plf_default', "")
REQUEST.set('_v_plf_first_item', 0)
REQUEST.set('_v_plf_items', sub_field_property_dict['item_list'])
REQUEST.set('_v_plf_size', sub_field_property_dict['size'])
return self.sub_widget[sub_field_property_dict['field_type']].render(
field,
field.generate_subfield_key(sub_field_property_dict['key'],
key=key),
sub_field_property_dict['value'],
REQUEST)
class ParallelListValidator(Validator.MultiSelectionValidator): class ParallelListValidator(Validator.MultiSelectionValidator):
property_names = Validator.MultiSelectionValidator.property_names property_names = Validator.MultiSelectionValidator.property_names
def __init__(self):
"""
Generate some subvalidator used for rendering.
"""
self.sub_validator = {
'ListField': Validator.SelectionValidatorInstance,
'MultiListField': Validator.MultiSelectionValidatorInstance,
}
def validate(self, field, key, REQUEST): def validate(self, field, key, REQUEST):
result_list = []
sub_field_id_list = field.sub_form.get_field_ids() result_list = []
hash_list = field._generateSubForm(None, REQUEST)
is_sub_field_required = 0 is_sub_field_required = 0
for sub_field_id in sub_field_id_list: for sub_field_property_dict in hash_list:
try: try:
sub_result_list = field.validate_sub_field(sub_field_id, REQUEST,key=key) sub_result_list = self.validate_sub_field(
if type(sub_result_list) not in (type([]), type(())): field,
field.generate_subfield_key(
sub_field_property_dict['key'],
validation=1, key=key),
REQUEST,
sub_field_property_dict)
if not isinstance(sub_result_list, (list, tuple)):
sub_result_list = [sub_result_list] sub_result_list = [sub_result_list]
else: else:
sub_result_list = list(sub_result_list) sub_result_list = list(sub_result_list)
result_list.extend(sub_result_list) result_list.extend(sub_result_list)
except ValidationError: except ValidationError:
is_sub_field_required = 1 is_sub_field_required = 1
result_list = filter( lambda x: x!='', result_list) result_list = [x for x in result_list if x!='']
if result_list == []: if result_list == []:
if field.get_value('required'): if field.get_value('required'):
self.raise_error('required_not_found', field) self.raise_error('required_not_found', field)
else: else:
if is_sub_field_required: if is_sub_field_required:
self.raise_error('required_not_found', field) self.raise_error('required_not_found', field)
return result_list return result_list
def validate_sub_field(self, field, id, REQUEST, sub_field_property_dict):
"""
Validates a subfield (as part of field validation).
"""
REQUEST.set('_v_plf_title', sub_field_property_dict['title'])
REQUEST.set('_v_plf_required', sub_field_property_dict['required'])
REQUEST.set('_v_plf_default', "")
REQUEST.set('_v_plf_items', sub_field_property_dict['item_list'])
REQUEST.set('_v_plf_size', sub_field_property_dict['size'])
return self.sub_validator[sub_field_property_dict['field_type']].validate(
field, id, REQUEST)
ParallelListWidgetInstance = ParallelListWidget() ParallelListWidgetInstance = ParallelListWidget()
ParallelListFieldValidatorInstance = ParallelListValidator() ParallelListFieldValidatorInstance = ParallelListValidator()
class ParallelListField(ZMIField): class ParallelListField(ZMIField):
meta_type = "ParallelListField" security = ClassSecurityInfo()
meta_type = "ParallelListField"
widget = ParallelListWidgetInstance widget = ParallelListWidgetInstance
validator = ParallelListFieldValidatorInstance validator = ParallelListFieldValidatorInstance
def render_htmlgrid(self, value=None, REQUEST=None, key=None): def render_htmlgrid(self, value=None, REQUEST=None, key=None):
""" """
render_htmlgrid returns a list of tuple (title, html render) render_htmlgrid returns a list of tuple (title, html render)
We will use title generated by the widget. We will use title generated by the widget.
""" """
key = self.generate_field_key(key=key) key = self.generate_field_key(key=key)
value = self._get_default(key, value, REQUEST) value = self._get_default(key, value, REQUEST)
html = self.widget.render_htmlgrid(self, key, value, REQUEST) html = self.widget.render_htmlgrid(self, key, value, REQUEST)
return html return html
def create_aggregated_list_sub_form(hash_list): def _generateSubForm(self, value, REQUEST):
""" item_list = [x for x in self.get_value('items') \
Generate ParallelListField sub field. if x not in (('',''), ['',''])]
"""
sub_form = BasicForm() value_list = value
sub_list_field_list = [] if not isinstance(value_list, (list, tuple)):
value_list = [value_list]
for sub_field_property_dict in hash_list:
field_class = getattr(StandardFields, empty_sub_field_property_dict = {
sub_field_property_dict['field_type']) 'key': 'default',
sub_field = field_class(sub_field_property_dict['key'], 'title': self.get_value('title'),
title=sub_field_property_dict['key'], 'required': 0,
required=sub_field_property_dict['required'], 'field_type': 'MultiListField',
default="", 'item_list': [],
items=sub_field_property_dict['item_list'], 'value': [],
size=sub_field_property_dict['size']) 'is_right_display': 0,
sub_list_field_list.append(sub_field) 'size': 5
}
sub_form.add_group("sub_list")
sub_form.add_fields(sub_list_field_list, "sub_list") hash_list = []
hash_script_id = self.get_value('hash_script_id')
return sub_form if hash_script_id not in [None, '']:
script = getattr(self, hash_script_id)
script_hash_list = script(
item_list,
value_list,
default_sub_field_property_dict=empty_sub_field_property_dict,
is_right_display=0)
hash_list.extend(script_hash_list)
else:
# No hash_script founded, generate a little hash_script
# to display only a MultiListField
default_sub_field_property_dict = empty_sub_field_property_dict.copy()
default_sub_field_property_dict.update({
'item_list': item_list,
'value': value_list,
})
hash_list.append(default_sub_field_property_dict)
# XXX Clean up old ParallelListField
try:
delattr(self, 'sub_form')
except KeyError:
pass
return hash_list
security.declareProtected('Access contents information', 'get_value')
def get_value(self, id, **kw):
"""
Get value for id.
Optionally pass keyword arguments that get passed to TALES
expression.
"""
REQUEST = kw.get('REQUEST')
key = '_v_plf_%s' % id
if (REQUEST is not None) and \
(REQUEST.has_key(key)):
result = REQUEST.get(key)
else:
result = ZMIField.get_value(self, id, **kw)
return result
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment