From a7c5fdf6ba2f313c2beb2a616c5dfd00b53a2f27 Mon Sep 17 00:00:00 2001
From: Nicolas Dumazet <nicolas.dumazet@nexedi.com>
Date: Mon, 15 Mar 2010 02:35:25 +0000
Subject: [PATCH] There's no precedence for listbox cell configuration. It's a
 boolean AND:

isEditable(listbox "field" cell) <=>
   isEditable(listbox_field) AND ("field" in listbox.editable_columns)


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@33704 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5Form/ListBox.py           |  9 +++----
 product/ERP5Form/tests/testListBox.py | 34 ++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 12 deletions(-)

diff --git a/product/ERP5Form/ListBox.py b/product/ERP5Form/ListBox.py
index ee144bc657..0b3d70bd95 100644
--- a/product/ERP5Form/ListBox.py
+++ b/product/ERP5Form/ListBox.py
@@ -2330,18 +2330,19 @@ class ListBoxHTMLRendererLine(ListBoxRendererLine):
           display_value = original_value
 
         enabled = editable_field.get_value('enabled', REQUEST=request)
+        editable = editable_field.get_value('editable', REQUEST=request)
         if enabled:
           # We need a way to pass the current line object (ie. brain) to the
           # field which is being displayed. Since the render_view API did not
           # permit this, we use the 'cell' value to pass the line object.
           request.set('cell', brain)
-          # Listbox 'editable' configuration should take precedence over
-          # individual field configuration
+          # Field is editable only if listbox lists it in editable columns AND
+          # if listbox_field is editable
           cell_html = editable_field.render(
             value=display_value,
             REQUEST=request,
             key=key,
-            editable=listbox_defines_column_as_editable,
+            editable=listbox_defines_column_as_editable and editable,
           )
           if isinstance(cell_html, str):
             cell_html = unicode(cell_html, encoding)
@@ -2351,7 +2352,7 @@ class ListBoxHTMLRendererLine(ListBoxRendererLine):
         if url is None:
           html = cell_html + error_message
         else:
-          if editable_field.get_value('editable', REQUEST=request):
+          if editable:
             html = u'%s' % cell_html
           else:
             html = u'<a href="%s">%s</a>' % (url, cell_html)
diff --git a/product/ERP5Form/tests/testListBox.py b/product/ERP5Form/tests/testListBox.py
index 8733d92f11..5c80596fb1 100644
--- a/product/ERP5Form/tests/testListBox.py
+++ b/product/ERP5Form/tests/testListBox.py
@@ -378,34 +378,49 @@ return []
     self._helperExtraAndCssInListboxLine("LinesField", True)
     self._helperExtraAndCssInListboxLine("LinesField", False)
 
-  def test_09_editablePropertyPrecedence(self):
+  def test_09_editablePropertyConfiguration(self):
     """
-      When listbox's editable column and listbox_xx's editable property
-      conflict, the listbox editable column choice should take over.
+      Test editable behavior of delegated columns.
+      A column is editable if and only if listbox_foo is editable AND foo is
+      in the editable columns of the listbox.
 
       For example, if listbox_foo is defined as editable, without
       having column "foo" listed as editable in the listbox, the field should
       not be rendered as editable
     """
+    self._helperEditableColumn(True, True, True)
+    self._helperEditableColumn(False, False, False)
+    self._helperEditableColumn(True, False, False)
+    self._helperEditableColumn(False, True, False)
+
+  def _helperEditableColumn(self, editable_in_listbox, editable_in_line,
+      expected_editable):
     portal = self.getPortal()
     portal.ListBoxZuite_reset()
 
-    field_name = 'noneditable'
-    field_id = 'listbox_noneditable'
+    field_name = 'editableproperty_%s_%s' \
+                    % (editable_in_listbox, editable_in_line)
+    field_name = field_name.lower()
+    field_id = 'listbox_%s' % field_name
 
     # Reset listbox properties
     listbox = portal.FooModule_viewFooList.listbox
-    listbox.ListBox_setPropertyList(
+    kw = dict(
       field_list_method = 'portal_catalog',
       field_columns = ['%s | Check extra' % field_name,],
     )
+    if editable_in_listbox:
+      kw['field_editable_columns'] = '%s | Check extra' % field_name
+
+    listbox.ListBox_setPropertyList(**kw)
+
 
     form = portal.FooModule_viewFooList
     form.manage_addField(field_id, field_name, "StringField")
     field = getattr(form, field_id)
 
     field.values['default'] = '42'
-    field.values['editable'] = True
+    field.values['editable'] = editable_in_line
     form.groups['bottom'].remove(field_id)
     form.groups['hidden'].append(field_id)
 
@@ -428,7 +443,10 @@ return []
                             '//input[starts-with(@name, $name)]',
                             name='field_%s_' % field_id,
                           )
-    self.assertEquals(len(editable_field_list), 0)
+
+    msg = "editable_in_listbox: %s, editable_in_line: %s" \
+            % (editable_in_listbox, editable_in_line)
+    self.assertEquals(len(editable_field_list) == 1, expected_editable, msg)
 
   def test_ObjectSupport(self):
     # make sure listbox supports rendering of simple objects
-- 
2.30.9