Commit 5e3d329a authored by Yusei Tahara's avatar Yusei Tahara

Support more than four dimensional matrix.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@37072 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 9c12c73c
...@@ -199,6 +199,7 @@ class MatrixBoxWidget(Widget.Widget): ...@@ -199,6 +199,7 @@ class MatrixBoxWidget(Widget.Widget):
if context is None: if context is None:
return '' return ''
as_cell_range_script_id = field.get_value('as_cell_range_script_id') as_cell_range_script_id = field.get_value('as_cell_range_script_id')
extra_dimension_category_list_list = [None]
if as_cell_range_script_id: if as_cell_range_script_id:
lines = [] lines = []
columns = [] columns = []
...@@ -214,9 +215,17 @@ class MatrixBoxWidget(Widget.Widget): ...@@ -214,9 +215,17 @@ class MatrixBoxWidget(Widget.Widget):
elif len_dimension_list >= 3: elif len_dimension_list >= 3:
lines, columns, tabs = dimension_list[:3] lines, columns, tabs = dimension_list[:3]
if len_dimension_list > 3: if len_dimension_list > 3:
raise NotImplementedError( extra_dimension_list = dimension_list[3:]
"Matrix box does not support %s dimensions" %
len_dimension_list) extra_dimension_category_label_dict = {}
extra_dimension_category_index_dict = {}
for extra_dimension in extra_dimension_list:
for index, (category, label) in enumerate(extra_dimension):
extra_dimension_category_label_dict[category] = label
extra_dimension_category_index_dict[category] = index
from Products.ERP5Type.Utils import cartesianProduct
extra_dimension_category_list_list = cartesianProduct(
[[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list])
else: else:
lines = field.get_value('lines') lines = field.get_value('lines')
columns = field.get_value('columns') columns = field.get_value('columns')
...@@ -251,174 +260,186 @@ class MatrixBoxWidget(Widget.Widget): ...@@ -251,174 +260,186 @@ class MatrixBoxWidget(Widget.Widget):
url = REQUEST.URL url = REQUEST.URL
list_html = '' list_html = ''
k = 0
# Create one table per tab
for tab in tabs:
tab_id = tab[0]
if (tab_id is not None) and \
(not isinstance(tab_id, (list, tuple))):
tab_id = [tab_id]
if render_format == 'list':
list_result_tab = [[tab[1]]]
# Create the header of the table - this should probably become DTML
first_tab = tab[1] or ''
header = """\
<!-- Matrix Content -->
%s<br/>
<div class="MatrixContent">
<table cellpadding="0" cellspacing="0" border="0">
""" % first_tab
# Create the footer. This should be replaced by DTML
# And work as some kind of parameter
footer = """\
<tr>
<td colspan="%s" align="center" valign="middle"
class="Data footer">
</td>
</tr>
</table>
</div>
""" % len(columns)
list_header = """\
<tr class="matrixbox_label_line"><td class=\"Data\"></td>
"""
for cname in columns:
first_column = cname[1] or ''
list_header = list_header + ("<td class=\"Data\">%s</td>\n" %
first_column)
if render_format == 'list':
list_result_tab[0].append(cname[1])
list_header = list_header + "</tr>"
# Build Lines for extra_dimension_category_list in extra_dimension_category_list_list:
i = 0 if extra_dimension_category_list is None:
j = 0 extra_dimension_label = ''
list_body = '' extra_dimension_position = ()
for l in lines: extra_dimension_index = ''
extra_dimension_category_list = []
if not i % 2: else:
td_css = 'DataA' extra_dimension_label = ','+','.join([extra_dimension_category_label_dict[category]
else: for category in extra_dimension_category_list])
td_css = 'DataB' extra_dimension_position = tuple([extra_dimension_category_index_dict[category]
list_body = list_body + '\n<tr class=\"%s\"><td class=\"matrixbox_label_column\">%s</td>' % (td_css, str(l[1])) for category in extra_dimension_category_list])
j = 0 extra_dimension_index = '_'+'_'.join(map(str, extra_dimension_position))
# Create one table per tab
k = 0
for tab in tabs:
tab_id = tab[0]
if (tab_id is not None) and \
(not isinstance(tab_id, (list, tuple))):
tab_id = [tab_id]
if render_format == 'list': if render_format == 'list':
list_result_lines = [ str(l[1]) ] list_result_tab = [[tab[1]]]
for c in columns: # Create the header of the table - this should probably become DTML
has_error = 0 first_tab = tab[1] or ''
column_id = c[0] header = """\
if (column_id is not None) and \ <!-- Matrix Content -->
(not isinstance(column_id, (list, tuple))): <div class="matrixbox_label_tab">%s</div>
column_id = [column_id] <div class="MatrixContent">
if column_id is None: <table cellpadding="0" cellspacing="0" border="0">
kw = [l[0]] """ % (first_tab+extra_dimension_label)
elif tab_id is None:
kw = [l[0], c[0]] # Create the footer. This should be replaced by DTML
# And work as some kind of parameter
footer = """\
<tr>
<td colspan="%s" align="center" valign="middle"
class="Data footer">
</td>
</tr>
</table>
</div>
""" % len(columns)
list_header = """\
<tr class="matrixbox_label_line"><td class=\"Data\"></td>
"""
for cname in columns:
first_column = cname[1] or ''
list_header = list_header + ("<td class=\"Data\">%s</td>\n" %
first_column)
if render_format == 'list':
list_result_tab[0].append(cname[1])
list_header = list_header + "</tr>"
# Build Lines
i = 0
j = 0
list_body = ''
for l in lines:
if not i % 2:
td_css = 'DataA'
else: else:
kw = [l[0], c[0]] + tab_id td_css = 'DataB'
kwd = {} list_body = list_body + '\n<tr class=\"%s\"><td class=\"matrixbox_label_column\">%s</td>' % (td_css, str(l[1]))
kwd['base_id'] = cell_base_id j = 0
cell = cell_getter_method(*kw, **kwd)
REQUEST['cell'] = cell if render_format == 'list':
list_result_lines = [ str(l[1]) ]
cell_body = ''
for c in columns:
for attribute_id in editable_attribute_ids: has_error = 0
my_field_id = '%s_%s' % (field.id, attribute_id) column_id = c[0]
if form.has_field(my_field_id): if (column_id is not None) and \
my_field = form.get_field(my_field_id) (not isinstance(column_id, (list, tuple))):
key = my_field.id + '_cell_%s_%s_%s' % (i,j,k) column_id = [column_id]
if cell is not None: if column_id is None:
attribute_value = my_field.get_value('default', kw = [l[0]]
cell=cell, cell_index=kw, cell_position = (i,j,k)) elif tab_id is None:
kw = [l[0], c[0]]
if render_format=='html': else:
display_value = attribute_value kw = [l[0], c[0]] + tab_id + extra_dimension_category_list
if field_errors: kwd = {}
# Display previous value in case of any error kwd['base_id'] = cell_base_id
# in this form because we have no cell to get cell = cell_getter_method(*kw, **kwd)
# value from REQUEST['cell'] = cell
display_value = REQUEST.get('field_%s' % key,
attribute_value) cell_body = ''
else:
display_value = attribute_value for attribute_id in editable_attribute_ids:
if field_errors.has_key(key): my_field_id = '%s_%s' % (field.id, attribute_id)
# Display error message if this cell has an error if form.has_field(my_field_id):
has_error = 1 my_field = form.get_field(my_field_id)
cell_body += '<span class="input">%s</span>%s' % ( key = my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index)
my_field.render(value=display_value, if cell is not None:
REQUEST=REQUEST, attribute_value = my_field.get_value('default',
key=key), cell=cell, cell_index=kw, cell_position = ((i,j,k)+extra_dimension_position))
translateString(field_errors[key].error_text))
else: if render_format=='html':
cell_body += '<span class="input">%s</span>' %\
my_field.render(
value=display_value,
REQUEST=REQUEST,
key=key)
elif render_format == 'list':
if not my_field.get_value('hidden'):
list_result_lines.append(attribute_value)
else:
attribute_value = my_field.get_value('default', cell=None,
cell_index=kw, cell_position=(i,j,k))
if render_format == 'html':
if field_errors:
# Display previous value in case of any error
# in this form because we have no cell to get
# value from
display_value = REQUEST.get('field_%s' % key,
attribute_value)
else:
display_value = attribute_value display_value = attribute_value
if field_errors.has_key(key): if field_errors:
# Display error message if this cell has an error # Display previous value in case of any error
has_error = 1 # in this form because we have no cell to get
cell_body += '<span class="input">%s</span>%s' % ( # value from
my_field.render(value=display_value, display_value = REQUEST.get('field_%s' % key,
REQUEST=REQUEST, attribute_value)
key=key), else:
translateString(field_errors[key].error_text)) display_value = attribute_value
else: if field_errors.has_key(key):
cell_body += '<span class="input">%s</span>' %\ # Display error message if this cell has an error
my_field.render( has_error = 1
value=display_value, cell_body += '<span class="input">%s</span>%s' % (
REQUEST=REQUEST, my_field.render(value=display_value,
key=key) REQUEST=REQUEST,
elif render_format == 'list': key=key),
list_result_lines.append(None) translateString(field_errors[key].error_text))
else:
css = td_css cell_body += '<span class="input">%s</span>' %\
if has_error : my_field.render(
css = 'error' value=display_value,
list_body = list_body + \ REQUEST=REQUEST,
('<td class=\"%s\">%s</td>' % (css, cell_body)) key=key)
j += 1
elif render_format == 'list':
list_body = list_body + '</tr>' if not my_field.get_value('hidden'):
i += 1 list_result_lines.append(attribute_value)
else:
attribute_value = my_field.get_value('default', cell=None,
cell_index=kw, cell_position=((i,j,k)+extra_dimension_position))
if render_format == 'html':
if field_errors:
# Display previous value in case of any error
# in this form because we have no cell to get
# value from
display_value = REQUEST.get('field_%s' % key,
attribute_value)
else:
display_value = attribute_value
if field_errors.has_key(key):
# Display error message if this cell has an error
has_error = 1
cell_body += '<span class="input">%s</span>%s' % (
my_field.render(value=display_value,
REQUEST=REQUEST,
key=key),
translateString(field_errors[key].error_text))
else:
cell_body += '<span class="input">%s</span>' %\
my_field.render(
value=display_value,
REQUEST=REQUEST,
key=key)
elif render_format == 'list':
list_result_lines.append(None)
css = td_css
if has_error :
css = 'error'
list_body = list_body + \
('<td class=\"%s\">%s</td>' % (css, cell_body))
j += 1
list_body = list_body + '</tr>'
i += 1
if render_format == 'list':
list_result_tab.append(list_result_lines)
list_html += header + list_header + \
list_body + footer
k += 1
if render_format == 'list': if render_format == 'list':
list_result_tab.append(list_result_lines) list_result.append(list_result_tab)
list_html += header + list_header + \
list_body + footer
k += 1
if render_format == 'list':
list_result.append(list_result_tab)
if render_format == 'list': if render_format == 'list':
return list_result return list_result
...@@ -442,6 +463,7 @@ class MatrixBoxValidator(Validator.Validator): ...@@ -442,6 +463,7 @@ class MatrixBoxValidator(Validator.Validator):
context = getattr(here,getter_method_id)() context = getattr(here,getter_method_id)()
if context is None: if context is None:
return {} return {}
extra_dimension_category_list_list = [None]
if as_cell_range_script_id: if as_cell_range_script_id:
lines = [] lines = []
columns = [] columns = []
...@@ -457,9 +479,17 @@ class MatrixBoxValidator(Validator.Validator): ...@@ -457,9 +479,17 @@ class MatrixBoxValidator(Validator.Validator):
elif len_dimension_list >= 3: elif len_dimension_list >= 3:
lines, columns, tabs = dimension_list[:3] lines, columns, tabs = dimension_list[:3]
if len_dimension_list > 3: if len_dimension_list > 3:
raise NotImplementedError( extra_dimension_list = dimension_list[3:]
"Matrix box does not support %s dimensions" %
len_dimension_list) extra_dimension_category_label_dict = {}
extra_dimension_category_index_dict = {}
for extra_dimension in extra_dimension_list:
for index, (category, label) in enumerate(extra_dimension):
extra_dimension_category_label_dict[category] = label
extra_dimension_category_index_dict[category] = index
from Products.ERP5Type.Utils import cartesianProduct
extra_dimension_category_list_list = cartesianProduct(
[[category for category, label in extra_dimension] for extra_dimension in extra_dimension_list])
else: else:
lines = field.get_value('lines') lines = field.get_value('lines')
columns = field.get_value('columns') columns = field.get_value('columns')
...@@ -484,58 +514,70 @@ class MatrixBoxValidator(Validator.Validator): ...@@ -484,58 +514,70 @@ class MatrixBoxValidator(Validator.Validator):
tab_ids = [x[0] for x in tabs] tab_ids = [x[0] for x in tabs]
editable_attribute_ids = [x[0] for x in editable_attributes] editable_attribute_ids = [x[0] for x in editable_attributes]
k = 0
result = {} result = {}
# Create one table per tab for extra_dimension_category_list in extra_dimension_category_list_list:
for tab_id in tab_ids: if extra_dimension_category_list is None:
if (tab_id is not None) and \ extra_dimension_label = ''
(not isinstance(tab_id, (list, tuple))): extra_dimension_position = ()
tab_id = [tab_id] extra_dimension_index = ''
extra_dimension_category_list = []
i = 0 else:
j = 0 extra_dimension_label = ','+','.join([extra_dimension_category_label_dict[category]
for l in line_ids: for category in extra_dimension_category_list])
extra_dimension_position = tuple([extra_dimension_category_index_dict[category]
for category in extra_dimension_category_list])
extra_dimension_index = '_'+'_'.join(map(str, extra_dimension_position))
k = 0
# Create one table per tab
for tab_id in tab_ids:
if (tab_id is not None) and \
(not isinstance(tab_id, (list, tuple))):
tab_id = [tab_id]
i = 0
j = 0 j = 0
for c in column_ids: for l in line_ids:
if c is None: j = 0
kw = [l] for c in column_ids:
elif tab_id is None: if c is None:
kw = [l, c] kw = [l]
else: elif tab_id is None:
kw = [l, c] + tab_id kw = [l, c]
kw = tuple(kw) else:
kwd = {} kw = [l, c] + tab_id + extra_dimension_category_list
kwd['base_id'] = cell_base_id kw = tuple(kw)
cell = cell_getter_method(*kw, **kwd) kwd = {}
kwd['base_id'] = cell_base_id
for attribute_id in editable_attribute_ids: cell = cell_getter_method(*kw, **kwd)
my_field_id = '%s_%s' % (field.id, attribute_id) for attribute_id in editable_attribute_ids:
if form.has_field(my_field_id):
my_field = form.get_field(my_field_id) my_field_id = '%s_%s' % (field.id, attribute_id)
if my_field.get_value('editable'): if form.has_field(my_field_id):
key = 'field_' + my_field.id + '_cell_%s_%s_%s' % (i,j,k) my_field = form.get_field(my_field_id)
attribute_value = my_field.get_value('default', if my_field.get_value('editable'):
cell=cell, cell_index=kw, cell_position = (i,j,k)) key = 'field_' + my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index)
value = None attribute_value = my_field.get_value('default',
try : cell=cell, cell_index=kw, cell_position = ((i,j,k)+extra_dimension_position))
value = my_field.validator.validate( value = None
my_field, key, REQUEST) try :
except ValidationError, err : value = my_field.validator.validate(
err.field_id = my_field.id + '_cell_%s_%s_%s' % (i,j,k) my_field, key, REQUEST)
error_list.append(err) except ValidationError, err :
err.field_id = my_field.id + '_cell_%s_%s_%s%s' % (i,j,k,extra_dimension_index)
if (attribute_value != value or \ error_list.append(err)
attribute_value not in ('',None,(),[])) \
and not my_field.get_value('hidden'): if (attribute_value != value or \
# Only validate modified values from visible fields attribute_value not in ('',None,(),[])) \
result.setdefault(kw, {})[attribute_id] = value and not my_field.get_value('hidden'):
else: # Only validate modified values from visible fields
if result.has_key(kw): result.setdefault(kw, {})[attribute_id] = value
result[kw][attribute_id] = value else:
j += 1 if result.has_key(kw):
i += 1 result[kw][attribute_id] = value
k += 1 j += 1
i += 1
k += 1
if len(error_list): if len(error_list):
raise FormValidationError(error_list, {}) raise FormValidationError(error_list, {})
return result 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