From 7b853a9e602a08d3314f524bce185207abfd3637 Mon Sep 17 00:00:00 2001 From: Bernat Brunet Torruella Date: Sat, 5 Mar 2016 17:51:35 +0100 Subject: [PATCH] Add patch to convert wizard to synchronous --- issue17881002_1.diff | 71 +++++++++++++++++++++++++++++++++++++++++ issue23901002_1.diff | 75 ++++++++++++++++++++++++++++++++++++++++++++ series | 3 ++ 3 files changed, 149 insertions(+) create mode 100644 issue17881002_1.diff create mode 100644 issue23901002_1.diff diff --git a/issue17881002_1.diff b/issue17881002_1.diff new file mode 100644 index 0000000..6ed1244 --- /dev/null +++ b/issue17881002_1.diff @@ -0,0 +1,71 @@ +# HG changeset patch +# User Cédric Krier +Disable button during click processing + + +The click event must be blocked when the screen method is called to limit +double execution. A double execution is still possible if the execution of the +action, which is asynchronous, is not started fast enough. + +issue5362 +review17881002 + +Index: src/view/form.js +=================================================================== + +--- a/public_data/sao/src/view/form.js ++++ b/public_data/sao/src/view/form.js +@@ -361,7 +361,12 @@ + }, + button_clicked: function(event) { + var button = event.data; +- this.screen.button(button.attributes); ++ button.el.prop('disabled', true); ++ try { ++ this.screen.button(button.attributes); ++ } finally { ++ button.el.prop('disabled', false); ++ } + }, + selected_records: function() { + if (this.screen.current_record) { + +Index: src/view/tree.js +=================================================================== + +--- a/public_data/sao/src/view/tree.js ++++ b/public_data/sao/src/view/tree.js +@@ -1509,7 +1509,7 @@ + }, + render: function(record) { + var button = new Sao.common.Button(this.attributes); +- button.el.click(record, this.button_clicked.bind(this)); ++ button.el.click([record, button], this.button_clicked.bind(this)); + var fields = jQuery.map(this.screen.model.fields, + function(field, name) { + if ((field.description.loading || 'eager') == +@@ -1526,7 +1526,8 @@ + return button.el; + }, + button_clicked: function(event) { +- var record = event.data; ++ var record = event.data[0]; ++ var button = event.data[1]; + if (record != this.screen.current_record) { + return; + } +@@ -1534,7 +1535,12 @@ + if (states.invisible || states.readonly) { + return; + } +- this.screen.button(this.attributes); ++ button.el.prop('disabled', true); ++ try { ++ this.screen.button(this.attributes); ++ } finally { ++ button.el.prop('disabled', false); ++ } + } + }); + + diff --git a/issue23901002_1.diff b/issue23901002_1.diff new file mode 100644 index 0000000..454d9bb --- /dev/null +++ b/issue23901002_1.diff @@ -0,0 +1,75 @@ +# HG changeset patch +# User Cédric Krier +Execute action synchronously + + +The clicked event must be blocked when the action is started, so the retrieval +of the action definition should be synchronous to be done inside the +try/finally. + +issue5362 +review23901002 + +Index: tryton/action/main.py +=================================================================== + +--- a/tryton/action/main.py ++++ b/tryton/action/main.py +@@ -54,31 +54,16 @@ + + @staticmethod + def execute(act_id, data, action_type=None, context=None): +- def get_action_type(actions): +- try: +- action, = actions() +- except RPCException: +- return ++ # Must be executed synchronously to avoid double execution ++ # on double click. ++ if not action_type: ++ action, = RPCExecute('model', 'ir.action', 'read', [act_id], ++ ['type'], context=context) + action_type = action['type'] +- exec_action(action_type) +- +- def exec_action(action_type): +- def callback(actions): +- try: +- action, = actions() +- except RPCException: +- return +- Action._exec_action(action, data, context=context) +- +- RPCExecute('model', action_type, 'search_read', +- [('action', '=', act_id)], 0, 1, None, None, +- context=context, callback=callback) +- +- if not action_type: +- RPCExecute('model', 'ir.action', 'read', [act_id], +- ['type'], context=context, callback=get_action_type) +- else: +- exec_action(action_type) ++ action, = RPCExecute('model', action_type, 'search_read', ++ [('action', '=', act_id)], 0, 1, None, None, ++ context=context) ++ Action._exec_action(action, data, context=context) + + @staticmethod + def _exec_action(action, data=None, context=None): + +Index: tryton/gui/window/view_form/view/list_gtk/widget.py +=================================================================== + +--- a/tryton/gui/window/view_form/view/list_gtk/widget.py ++++ b/tryton/gui/window/view_form/view/list_gtk/widget.py +@@ -909,4 +909,8 @@ + if state_changes.get('invisible') \ + or state_changes.get('readonly'): + return True +- self.view.screen.button(self.attrs) ++ widget.handler_block_by_func(self.button_clicked) ++ try: ++ self.view.screen.button(self.attrs) ++ finally: ++ widget.handler_unblock_by_func(self.button_clicked) + diff --git a/series b/series index b3ef429..3679688 100644 --- a/series +++ b/series @@ -33,6 +33,9 @@ issue19491002_1.diff issue20451002_1.diff issue5118.diff issue18801002_1.diff +issue23901002_1.diff +issue17881002_1.diff + # Ignore next patches #incremental_wait_in_retries.diff # Uncomment in calfruitos and basidelta