Reviewers: ,


Please review this at http://codereview.tryton.org/537002/

Affected files:
  M tryton/gui/window/view_form/model/record.py
  M tryton/gui/window/view_form/screen/screen.py
  M tryton/gui/window/view_form/view/form_gtk/one2many.py
  M tryton/gui/window/view_form/view/list.py
  M tryton/gui/window/view_form/view/list_gtk/editabletree.py
  M tryton/gui/window/view_form/view/list_gtk/parser.py
  M tryton/gui/window/win_form.py


Index: tryton/gui/window/view_form/model/record.py
===================================================================

--- a/tryton/gui/window/view_form/model/record.py
+++ b/tryton/gui/window/view_form/model/record.py
@@ -264,6 +264,15 @@
             result.update(field.get_timestamp(self))
         return result

+    def pre_validate(self):
+        values = self.get()
+        try:
+            RPCExecute('model', self.model_name, 'pre_validate', values,
+                context=self.context_get())
+        except RPCException:
+            return False
+        return True
+
     def save(self, force_reload=True):
         if self.id < 0 or self.modified:
             if self.id < 0:

Index: tryton/gui/window/view_form/screen/screen.py
===================================================================

--- a/tryton/gui/window/view_form/screen/screen.py
+++ b/tryton/gui/window/view_form/screen/screen.py
@@ -81,6 +81,7 @@
         self.expanded_nodes = collections.defaultdict(
             lambda: collections.defaultdict(lambda: None))
         self.domain_parser = None
+        self.pre_validate = False

         if mode:
             self.view_to_load = mode[1:]

Index: tryton/gui/window/view_form/view/form_gtk/one2many.py
===================================================================

--- a/tryton/gui/window/view_form/view/form_gtk/one2many.py
+++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py
@@ -173,6 +173,7 @@
             views_preload=attrs.get('views', {}),
             row_activate=self._on_activate,
             exclude_field=attrs.get('relation_field', None))
+        self.screen.pre_validate = bool(int(attrs.get('pre_validate', 0)))
         self.screen.signal_connect(self, 'record-message', self._sig_label)

         self.widget.pack_start(self.screen.widget, expand=True, fill=True)
@@ -282,16 +283,23 @@
                     and access['write']
                     and access['read']))

-    def _sig_new(self, widget):
-        if not common.MODELACCESS[self.screen.model_name]['create']:
-            return
+    def _validate(self):
         self.view.set_value()
         record = self.screen.current_record
         if record:
             fields = self.screen.current_view.get_fields()
             if not record.validate(fields):
                 self.screen.display()
-                return
+                return False
+            if self.screen.pre_validate and not record.pre_validate():
+                return False
+        return True
+
+    def _sig_new(self, widget):
+        if not common.MODELACCESS[self.screen.model_name]['create']:
+            return
+        if not self._validate():
+            return
         ctx = {}
         ctx.update(self.field.context_get(self.record))
         sequence = None
@@ -316,33 +324,20 @@
     def _sig_edit(self, widget=None):
         if not common.MODELACCESS[self.screen.model_name]['read']:
             return
-        self.view.set_value()
+        if not self._validate():
+            return
         record = self.screen.current_record
         if record:
-            fields = self.screen.current_view.get_fields()
-            if not record.validate(fields):
-                self.screen.display()
-                return
             WinForm(self.screen, lambda a: None)

     def _sig_next(self, widget):
-        self.view.set_value()
-        record = self.screen.current_record
-        if record:
-            fields = self.screen.current_view.get_fields()
-            if not record.validate(fields):
-                self.screen.display()
-                return
+        if not self._validate():
+            return
         self.screen.display_next()

     def _sig_previous(self, widget):
-        self.view.set_value()
-        record = self.screen.current_record
-        if record:
-            fields = self.screen.current_view.get_fields()
-            if not record.validate(fields):
-                self.screen.display()
-                return
+        if not self._validate():
+            return
         self.screen.display_prev()

     def _sig_remove(self, widget, remove=False):

Index: tryton/gui/window/view_form/view/list.py
===================================================================

--- a/tryton/gui/window/view_form/view/list.py
+++ b/tryton/gui/window/view_form/view/list.py
@@ -708,14 +708,14 @@
             else:
                 self.screen.current_record = None

-        if hasattr(self.widget_tree, 'editable') \
-                and self.widget_tree.editable \
-                and not self.screen.parent \
-                and previous_record != self.screen.current_record:
-            if previous_record:
-                def go_previous():
-                    self.screen.current_record = previous_record
-                    self.set_cursor()
+        if (hasattr(self.widget_tree, 'editable')
+                and self.widget_tree.editable
+                and previous_record):
+            def go_previous():
+                self.screen.current_record = previous_record
+                self.set_cursor()
+            if (not self.screen.parent
+                    and previous_record != self.screen.current_record):

                 def save():
                     if not previous_record.destroyed:
@@ -727,6 +727,15 @@
                     return True
                 # Delay the save to let GTK process the current event
                 gobject.idle_add(save)
+            elif (previous_record != self.screen.current_record
+                    and self.screen.pre_validate):
+
+                def pre_validate():
+                    if not previous_record.destroyed:
+                        if not previous_record.pre_validate():
+                            go_previous()
+ # Delay the pre_validate to let GTK process the current event
+                gobject.idle_add(pre_validate)
         self.update_children()

     def set_value(self):

Index: tryton/gui/window/view_form/view/list_gtk/editabletree.py
===================================================================

--- a/tryton/gui/window/view_form/view/list_gtk/editabletree.py
+++ b/tryton/gui/window/view_form/view/list_gtk/editabletree.py
@@ -184,6 +184,9 @@
                         break
                 self.set_cursor(path, col, True)
                 return True
+            if self.screen.pre_validate:
+                if not record.pre_validate():
+                    return True
             if not self.screen.parent:
                 obj_id = record.save()
                 if not obj_id:

Index: tryton/gui/window/view_form/view/list_gtk/parser.py
===================================================================

--- a/tryton/gui/window/view_form/view/list_gtk/parser.py
+++ b/tryton/gui/window/view_form/view/list_gtk/parser.py
@@ -711,6 +711,7 @@

         screen = Screen(relation, mode=['tree', 'form'],
             exclude_field=field.attrs.get('relation_field'))
+        screen.pre_validate = bool(int(self.attrs.get('pre_validate', 0)))
         screen.group = group

         def open_callback(result):

Index: tryton/gui/window/win_form.py
===================================================================

--- a/tryton/gui/window/win_form.py
+++ b/tryton/gui/window/win_form.py
@@ -398,6 +398,8 @@
                 and self.screen.current_record is not None):
             validate = self.screen.current_record.validate(
                 self.screen.current_view.get_fields())
+            if validate and self.screen.pre_validate:
+                validate = self.screen.current_record.pre_validate()
             if validate and self.save_current:
                 if not self.screen.save_current():
                     validate = False



--
[email protected] mailing list

Reply via email to