From 2c85f197991d5b2880071a88991809cd2f4a72fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 4 Mar 2014 11:49:11 +0100 Subject: [PATCH] Don't change group value when it is not needed The group of xxx2many must only be changed for set and set_default. Other methods should keep the removed/deleted records but as the older group was destroyed this information is lost. issue3724 review3971002 --- tryton/gui/window/view_form/model/field.py | 126 ++++++++------------- 1 file changed, 46 insertions(+), 80 deletions(-) diff --git a/tryton/gui/window/view_form/model/field.py b/tryton/gui/window/view_form/model/field.py index e3bc13a16a..c09958b592 100644 --- a/tryton/gui/window/view_form/model/field.py +++ b/tryton/gui/window/view_form/model/field.py @@ -490,25 +490,29 @@ class O2MField(CharField): return record.parent.signal('record-modified') - def _set_default_value(self, record): + def _set_default_value(self, record, fields=None): if record.value.get(self.name) is not None: return from group import Group parent_name = self.attrs.get('relation_field', '') - group = Group(self.attrs['relation'], {}, + fields = fields or {} + if not fields and record.model_name == self.attrs['relation']: + fields = record.group.fields + group = Group(self.attrs['relation'], fields, parent=record, parent_name=parent_name, child_name=self.name, context=self.context, parent_datetime_field=self.attrs.get('datetime_field')) - if record.model_name == self.attrs['relation']: - group.fields = record.group.fields + record.value[self.name] = group + self._connect_value(group) + + def _connect_value(self, group): group.signal_connect(group, 'group-changed', self._group_changed) group.signal_connect(group, 'group-list-changed', self._group_list_changed) group.signal_connect(group, 'group-cleared', self._group_cleared) group.signal_connect(group, 'record-modified', self._record_modified) - record.value[self.name] = group def get_client(self, record): self._set_default_value(record) @@ -578,13 +582,41 @@ class O2MField(CharField): return result def _set_value(self, record, value, default=False): - from group import Group - + self._set_default_value(record) + group = record.value[self.name] if not value or (len(value) and isinstance(value[0], (int, long))): mode = 'list ids' else: mode = 'list values' + if mode == 'list values' and len(value): + context = self.context_get(record) + field_names = set(f for v in value for f in v + if f not in group.fields) + if field_names: + try: + fields = RPCExecute('model', self.attrs['relation'], + 'fields_get', list(field_names), context=context) + except RPCException: + return + group.load_fields(fields) + + if mode == 'list ids': + for old_record in group: + group.remove(old_record, remove=True, signal=False) + group.load(value) + else: + for vals in value: + new_record = record.value[self.name].new(default=False) + if default: + new_record.set_default(vals) + group.add(new_record) + else: + new_record.id *= -1 # Don't consider record as unsaved + new_record.set(vals) + group.append(new_record) + + def set(self, record, value, _default=False): group = record.value.get(self.name) fields = {} if group is not None: @@ -597,44 +629,14 @@ class O2MField(CharField): if fields: fields = dict((fname, field.attrs) for fname, field in fields.iteritems()) - if mode == 'list values' and len(value): - context = self.context_get(record) - field_names = set(f for v in value for f in v if f not in fields) - if field_names: - try: - fields.update(RPCExecute('model', self.attrs['relation'], - 'fields_get', list(field_names), context=context)) - except RPCException: - return - parent_name = self.attrs.get('relation_field', '') - group = Group(self.attrs['relation'], fields, - parent=record, parent_name=parent_name, - child_name=self.name, - context=self.context, - parent_datetime_field=self.attrs.get('datetime_field')) - record.value[self.name] = group - if mode == 'list ids': - group.load(value) - else: - for vals in value: - new_record = record.value[self.name].new(default=False) - if default: - new_record.set_default(vals) - group.add(new_record) - else: - new_record.id *= -1 # Don't consider record as unsaved - new_record.set(vals) - group.append(new_record) - group.signal_connect(group, 'group-changed', self._group_changed) - group.signal_connect(group, 'group-list-changed', - self._group_list_changed) - group.signal_connect(group, 'group-cleared', self._group_cleared) - group.signal_connect(group, 'record-modified', self._record_modified) - return group + record.value[self.name] = None + self._set_default_value(record, fields=fields) + group = record.value[self.name] - def set(self, record, value): - self._set_value(record, value, default=False) + group.signal_unconnect(group) + self._set_value(record, value, default=_default) + self._connect_value(group) def set_client(self, record, value, force_change=False): # domain inversion could try to set id as value @@ -655,16 +657,10 @@ class O2MField(CharField): record.signal('record-changed') def set_default(self, record, value): - previous_group = record.value.get(self.name) - group = self._set_value(record, value, default=True) - if previous_group: - group.record_deleted.extend(x for x in previous_group if x.id >= 0) - group.record_deleted.extend(previous_group.record_deleted) - group.record_removed.extend(previous_group.record_removed) + self.set(record, value, _default=True) record.modified_fields.setdefault(self.name) def set_on_change(self, record, value): - self._set_default_value(record) if isinstance(value, (list, tuple)): self._set_value(record, value) record.modified_fields.setdefault(self.name) @@ -752,36 +748,6 @@ class O2MField(CharField): class M2MField(O2MField): - def set(self, record, value): - from group import Group - group = record.value.get(self.name) - fields = {} - if group is not None: - fields = group.fields.copy() - # Unconnect to prevent infinite loop - group.signal_unconnect(group) - group.destroy() - elif record.model_name == self.attrs['relation']: - fields = record.group.fields - parent_name = self.attrs.get('relation_field', '') - group = Group(self.attrs['relation'], {}, - parent=record, parent_name=parent_name, - child_name=self.name, - context=self.context, - parent_datetime_field=self.attrs.get('datetime_field')) - if record.value.get(self.name): - group.record_removed.extend(record.value[self.name]) - group.record_deleted.extend(record.value[self.name].record_deleted) - group.record_removed.extend(record.value[self.name].record_removed) - record.value[self.name] = group - group.fields = fields - group.load(value) - group.signal_connect(group, 'group-changed', self._group_changed) - group.signal_connect(group, 'group-list-changed', - self._group_list_changed) - group.signal_connect(group, 'group-cleared', self._group_cleared) - group.signal_connect(group, 'record-modified', self._record_modified) - def get_on_change_value(self, record): return self.get_eval(record)