← Back to team overview

openerp-dev-web team mailing list archive

[Merge] lp:~openerp-dev/openobject-client/trunk-improve_onchange-rga into lp:openobject-client

 

Ravi Gadhia (OpenERP) has proposed merging lp:~openerp-dev/openobject-client/trunk-improve_onchange-rga into lp:openobject-client.

Requested reviews:
  Naresh(OpenERP) (nch-openerp)
Related bugs:
  Bug #769538 in OpenERP GTK Client: "Onchange on one2many and many2one"
  https://bugs.launchpad.net/openobject-client/+bug/769538
  Bug #769542 in OpenERP GTK Client: "Onchange that modifies an image is not refreshed from returned value"
  https://bugs.launchpad.net/openobject-client/+bug/769542

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-client/trunk-improve_onchange-rga/+merge/59918

Hello,
     This branch contain following improvements:
     1) split binary and image widget at model level
     2) remove unused argument
     3) improve recursive on_change event

     Bug fixed:
     https://bugs.launchpad.net/openobject-client/+bug/769538
     https://bugs.launchpad.net/openobject-client/+bug/769542
     https://bugs.launchpad.net/openobject-client/+bug/769544


-- 
https://code.launchpad.net/~openerp-dev/openobject-client/trunk-improve_onchange-rga/+merge/59918
Your team OpenERP R&D Team is subscribed to branch lp:~openerp-dev/openobject-client/trunk-improve_onchange-rga.
=== modified file 'bin/widget/model/field.py'
--- bin/widget/model/field.py	2011-04-20 09:34:21 +0000
+++ bin/widget/model/field.py	2011-05-04 13:07:00 +0000
@@ -94,7 +94,7 @@
         self.get_state_attrs(model)['valid'] = ok
         return ok
 
-    def set(self, model, value, test_state=True, modified=False):
+    def set(self, model, value, modified=False):
         if isinstance(value, basestring):
             value = value.strip()
         model.value[self.name] = value
@@ -106,9 +106,9 @@
     def get(self, model, check_load=True, readonly=True, modified=False):
         return model.value.get(self.name, False) or False
 
-    def set_client(self, model, value, test_state=True, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.value.get(self.name, False)
-        self.set(model, value, test_state)
+        self.set(model, value)
         if (internal or False) != (model.value.get(self.name,False) or False):
             model.modified = True
             model.modified_fields.setdefault(self.name)
@@ -169,7 +169,7 @@
             if self.attrs.get('required', False):
                 self.get_state_attrs(model)['required'] = self.attrs['required']
         if 'value' in state_changes:
-            self.set(model, state_changes['value'], test_state=False, modified=True)
+            self.set(model, state_changes['value'], modified=True)
     
     def get_state_attrs(self, model):
         if self.name not in model.state_attrs:
@@ -177,22 +177,6 @@
         return model.state_attrs[self.name]
 
 class BinaryField(CharField):
-    def __check_model(self, model):
-        assert self.name in model.mgroup.mfields
-
-    def __check_load(self, model, modified, bin_size):
-        if model.id and (self.name not in model.value or (model.value[self.name] is None)):
-            c = rpc.session.context.copy()
-            c.update(model.context_get())
-            c['bin_size'] = bin_size
-            data = model.rpc.read([model.id], [self.name], c)
-            if data:
-                value = data[0][self.name]
-                self.set(model, value, modified=modified, get_binary_size=bin_size)
-
-    def get_size_name(self):
-        return "%s.size" % self.name
-
     def validate(self, model):
         ok = True
         if bool(self.get_state_attrs(model).get('required', 0)):
@@ -202,65 +186,58 @@
         self.get_state_attrs(model)['valid'] = ok
         return ok
 
-    def set(self, model, value, test_state=True, modified=False, get_binary_size=True):
-        self.__check_model(model)
-        if model.is_wizard():
-            get_binary_size = False
-        model.value[self.name] = None
-        name = get_binary_size and self.get_size_name() or self.name
-        model.value[name] = value
-        if (not get_binary_size) and value:
-            model.value[self.get_size_name()] = tools.human_size(len(value))
-        if not value:
-            model.value[self.get_size_name()] = ""
+    def set(self, model, value, modified=False):
+        model.value[self.name] = value
+        if value:
+            value = tools.human_size(len(value))
+        model.value["%s.size" % self.name] = value
         if modified:
             model.modified = True
             model.modified_fields.setdefault(self.name)
         return True
 
-    def get(self, model, check_load=True, readonly=True, modified=False):
-        self.__check_model(model)
-        if check_load:
-            self.__check_load(model, modified, False)
-        res = model.value.get(self.name, False)
-        if not res:
-            return model.value.get(self.get_size_name(), False) or False
-        return res
-
     def get_client(self, model):
-        self.__check_model(model)
-        self.__check_load(model, False, True)
-        return model.value.get(self.get_size_name(), False) or False
+        return model.value.get("%s.size" % self.name, False) 
 
-    def set_client(self, model, value, test_state=True, force_change=False):
-        self.__check_model(model)
+    def set_client(self, model, value):
         before = self.get(model)
-        self.set(model, value, test_state, get_binary_size=False)
+        self.set(model, value)
         if before != self.get(model):
             model.modified = True
             model.modified_fields.setdefault(self.name)
             self.sig_changed(model)
             model.signal('record-changed', model)
 
+class ImageField(CharField):
+    
+    def set(self, model, value, modified=False):
+        model.value[self.name] = value
+        if not value:
+            model.value[self.name] = ''
+        if modified:
+            model.modified = True
+            model.modified_fields.setdefault(self.name)
+        return True
+
 
 class SelectionField(CharField):
-    def set(self, model, value, test_state=True, modified=False):
+    def set(self, model, value, modified=False):
         value = isinstance(value,(list,tuple)) and len(value) and value[0] or value
 
         if not self.get_state_attrs(model).get('required', False) and value is None:
-            super(SelectionField, self).set(model, value, test_state, modified)
+            super(SelectionField, self).set(model, value, modified)
 
         if value in [sel[0] for sel in self.attrs['selection']]:
-            super(SelectionField, self).set(model, value, test_state, modified)
+            super(SelectionField, self).set(model, value, modified)
 
 class FloatField(CharField):
     def validate(self, model):
         self.get_state_attrs(model)['valid'] = True
         return True
 
-    def set_client(self, model, value, test_state=True, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.value[self.name]
-        self.set(model, value, test_state)
+        self.set(model, value)
         if abs(float(internal or 0.0) - float(model.value[self.name] or 0.0)) >= (10.0**(-1-int(self.attrs.get('digits', (12,4))[1]))):
             if not self.get_state_attrs(model).get('readonly', False):
                 model.modified = True
@@ -279,9 +256,9 @@
         self.get_state_attrs(model)['valid'] = True
         return True
 
-    def set_client(self, model, value, test_state=True, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.value.get(self.name, False)
-        self.set(model, value, test_state)
+        self.set(model, value)
         if int(internal or False) != (model.value.get(self.name,False) or False):
             model.modified = True
             model.modified_fields.setdefault(self.name)
@@ -308,7 +285,7 @@
             return model.value[self.name][1]
         return False
 
-    def set(self, model, value, test_state=False, modified=False):
+    def set(self, model, value, modified=False):
         if value and isinstance(value, (int, str, unicode, long)):
             rpc2 = RPCProxy(self.attrs['relation'])
             result = rpc2.name_get([value], rpc.session.context)
@@ -319,9 +296,9 @@
             model.modified = True
             model.modified_fields.setdefault(self.name)
 
-    def set_client(self, model, value, test_state=False, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.value[self.name]
-        self.set(model, value, test_state)
+        self.set(model, value)
         if internal != model.value[self.name]:
             model.modified = True
             model.modified_fields.setdefault(self.name)
@@ -353,7 +330,7 @@
             res = model.pager_cache[self.name]
         return res or model.value[self.name] or []
 
-    def set(self, model, value, test_state=False, modified=False):
+    def set(self, model, value, modified=False):
         ## The case where M2M may appear in a domain as string
         ## eg: if I have a domain on partner list view as
         ## [('categ_id','=','supplier')]
@@ -369,9 +346,9 @@
             model.modified = True
             model.modified_fields.setdefault(self.name)
 
-    def set_client(self, model, value, test_state=False, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.pager_cache.get(self.name, [])
-        self.set(model, value, test_state, modified=False)
+        self.set(model, value, modified=False)
         if model.is_m2m_modified or set(internal) != set(value):
             model.is_m2m_modified = False
             model.modified = True
@@ -424,7 +401,7 @@
             result.append((2, model2.id, False))
         return result
 
-    def set(self, model, value, test_state=False, modified=False):
+    def set(self, model, value, modified=False):
         if value and not isinstance(value[0], int):
             model = self.set_default(model, value)
             return
@@ -438,8 +415,8 @@
         model.value[self.name].pre_load(value, display=False)
         #self.internal.signal_connect(self.internal, 'model-changed', self._model_changed)
 
-    def set_client(self, model, value, test_state=False, force_change=False):
-        self.set(model, value, test_state=test_state)
+    def set_client(self, model, value, force_change=False):
+        self.set(model, value)
         model.signal('record-changed', model)
 
     def set_default(self, model, value):
@@ -504,7 +481,7 @@
             return '%s,%d' % (val[0], val[1][0])
         return False
 
-    def set_client(self, model, value, test_state=False, force_change=False):
+    def set_client(self, model, value, force_change=False):
         internal = model.value[self.name]
         model.value[self.name] = value
         if (internal or False) != (model.value[self.name] or False):
@@ -513,7 +490,7 @@
             self.sig_changed(model)
             model.signal('record-changed', model)
 
-    def set(self, model, value, test_state=False, modified=False):
+    def set(self, model, value, modified=False):
         if not value:
             model.value[self.name] = False
             return
@@ -541,7 +518,7 @@
     'reference' : ReferenceField,
     'selection': SelectionField,
     'boolean': IntegerField,
-    'image': BinaryField,
+    'image': ImageField,
     'binary': BinaryField,
 }
 

=== modified file 'bin/widget/model/record.py'
--- bin/widget/model/record.py	2011-04-20 12:46:44 +0000
+++ bin/widget/model/record.py	2011-05-04 13:07:00 +0000
@@ -18,7 +18,7 @@
 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
-
+import logging
 import re
 import time
 import common
@@ -238,12 +238,14 @@
         self._loaded = True
         self.signal('record-changed')
 
-    def set(self, val, modified=False, signal=True):
+    def set(self, val, modified=False, signal=True, check_on_change=False):
         later = {}
         for fieldname, value in val.items():
             if fieldname == CONCURRENCY_CHECK_FIELD:
                 self._concurrency_check_data = value
             if fieldname not in self.mgroup.mfields:
+                if check_on_change:
+                    logging.getLogger('on_change').warning('%s object has no field %s' % (self.resource, fieldname))
                 continue
             if isinstance(self.mgroup.mfields[fieldname], field.O2MField):
                  self.pager_cache[fieldname] = value
@@ -253,7 +255,9 @@
                 self.pager_cache[fieldname] = value
 
             self.mgroup.mfields[fieldname].set(self, value, modified=modified)
-
+            if check_on_change:
+                self.mgroup.mfields[fieldname].sig_changed(self)
+            
         for fieldname, value in later.items():
             self.mgroup.mfields[fieldname].set(self, value, modified=modified)
         self._loaded = True
@@ -271,7 +275,6 @@
             return
         c = rpc.session.context.copy()
         c.update(self.context_get())
-        c['bin_size'] = True
         res = self.rpc.read([self.id], fields, c)
         if res:
             value = res[0]
@@ -310,7 +313,7 @@
         ids = self.id and [self.id] or []
         response = getattr(self.rpc, func_name)(ids, *args)
         if response:
-            self.set(response.get('value', {}), modified=True)
+            self.set(response.get('value', {}), modified=True, check_on_change=True)
             if 'domain' in response:
                 for fieldname, value in response['domain'].items():
                     if fieldname not in self.mgroup.mfields:

=== modified file 'bin/widget/view/form_gtk/image.py'
--- bin/widget/view/form_gtk/image.py	2011-04-20 09:31:42 +0000
+++ bin/widget/view/form_gtk/image.py	2011-05-04 13:07:00 +0000
@@ -95,9 +95,7 @@
 
         self.alignment.add(self.hbox)
         self.widget.pack_start(self.alignment, expand=False, fill=False)
-
         self.update_img()
-        self._old_model = False
 
     def sig_add(self, widget):
         filter_all = gtk.FileFilter()
@@ -178,9 +176,6 @@
                 log = logging.getLogger('common')
                 log.warning(_('Image corrupted'))
 
-                
-                
-
         pixbuf = None
         for type in ('jpeg', 'gif', 'png', 'bmp'):
             loader = gtk.gdk.PixbufLoader(type)
@@ -221,11 +216,9 @@
     def display(self, model, model_field):
         if not model_field:
             return False
-        if (self._old_model != model) or not self._value:
-            self._value = model_field.get(model)
+        self._value = model_field.get(model)
         super(image_wid, self).display(model, model_field)
         self.update_img()
-        self._old_model = model
 
     def set_value(self, model, model_field):
         return model_field.set_client(model, self._value or False)

=== modified file 'bin/widget/view/tree_gtk/parser.py'
--- bin/widget/view/tree_gtk/parser.py	2011-03-20 11:26:23 +0000
+++ bin/widget/view/tree_gtk/parser.py	2011-05-04 13:07:00 +0000
@@ -276,7 +276,7 @@
         else:
             field.get_state_attrs(model)['required'] = field.attrs.get('required',False)
         if 'value' in state_changes:
-            field.set(model, state_changes['value'], test_state=False, modified=True)
+            field.set(model, state_changes['value'], modified=True)
 
     def setter(self, column, cell, store, iter):
         model = store.get_value(iter, 0)


Follow ups