From 4ca7d9b11a538a609093eb73fad047a32092d2c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 4 Mar 2014 11:44:06 +0100 Subject: [PATCH] Use explicit callback instead of implicit gtk main iteration in rpc calls The implicit gtk main iteration leads to bad ordered processing of events. So as explicit is better than implicit, rpc calls that don't need to block until the result use a callback. review3461002 --- tryton/action/main.py | 34 +++-- tryton/common/common.py | 79 ++++++++---- tryton/common/completion.py | 31 +++-- tryton/common/popup_menu.py | 64 +++++----- tryton/gui/main.py | 123 +++++++++--------- tryton/gui/window/view_form/model/field.py | 13 +- tryton/gui/window/view_form/model/group.py | 4 +- tryton/gui/window/view_form/model/record.py | 32 ++--- tryton/gui/window/wizard.py | 134 ++++++++++---------- tryton/rpc.py | 10 -- 10 files changed, 276 insertions(+), 248 deletions(-) diff --git a/tryton/action/main.py b/tryton/action/main.py index 9ede0112af..3dc76fb4de 100644 --- a/tryton/action/main.py +++ b/tryton/action/main.py @@ -54,23 +54,31 @@ class Action(object): @staticmethod def execute(act_id, data, action_type=None, context=None): - if not action_type: - res = False + def get_action_type(actions): try: - res, = RPCExecute('model', 'ir.action', 'read', [act_id], - ['type'], context=context) + action, = actions() except RPCException: return - if not res: - raise Exception('ActionNotFound') - action_type = res['type'] - try: - res, = RPCExecute('model', action_type, 'search_read', + 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) + + RPCExecute('model', action_type, 'search_read', [('action', '=', act_id)], 0, 1, None, None, - context=context) - except RPCException: - return - Action._exec_action(res, data) + 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) @staticmethod def _exec_action(action, data=None, context=None): diff --git a/tryton/common/common.py b/tryton/common/common.py index 83fefe9e7a..9fe4e685b6 100644 --- a/tryton/common/common.py +++ b/tryton/common/common.py @@ -14,7 +14,6 @@ import unicodedata from functools import partial from tryton.config import CONFIG from tryton.config import TRYTON_ICON, PIXMAPS_DIR -import time import sys import xmlrpclib try: @@ -1276,42 +1275,59 @@ class RPCProgress(object): self.error = True self.res = False self.exception = exception - return True - if not self.res: - self.error = True + else: + if not self.res: + self.error = True + if self.callback: + # Post to GTK queue to be run by the main thread + gobject.idle_add(self.process) return True - def run(self, process_exception_p=True, main_iteration_p=True): - session = rpc._SESSION - thread.start_new_thread(self.start, ()) + def run(self, process_exception_p=True, callback=None): + self.process_exception_p = process_exception_p + self.callback = callback + self.session = rpc._SESSION + if self.parent.window: + watch = gtk.gdk.Cursor(gtk.gdk.WATCH) + self.parent.window.set_cursor(watch) - watch = None - i = 0 - while (not self.res) and (not self.error): - i += 1 - if i > 1: - watch = gtk.gdk.Cursor(gtk.gdk.WATCH) - self.parent.window.set_cursor(watch) - if main_iteration_p: - with gtk.gdk.lock: - while gtk.events_pending(): - gtk.main_iteration() - time.sleep(0.1) + if callback: + thread.start_new_thread(self.start, ()) + return + else: + self.start() + return self.process() + + def process(self): if self.parent.window: self.parent.window.set_cursor(None) if self.exception: - if process_exception_p: + if self.process_exception_p: def rpc_execute(*args): return RPCProgress('execute', - args).run(process_exception_p, main_iteration_p) + args).run(self.process_exception_p, self.callback) result = process_exception(self.exception, *self.args, - rpc_execute=rpc_execute, session=session) + rpc_execute=rpc_execute, session=self.session) + if self.callback: + return if result is False: - raise RPCException(self.exception) - return result + self.exception = RPCException(self.exception) + else: + self.exception = None + self.res = result else: + self.exception + + def return_(): + if self.exception: raise self.exception - return self.res + else: + return self.res + + if self.callback: + self.callback(return_) + else: + return return_() def RPCExecute(*args, **kwargs): @@ -1320,8 +1336,17 @@ def RPCExecute(*args, **kwargs): rpc_context.update(kwargs['context']) args = args + (rpc_context,) process_exception = kwargs.get('process_exception', True) - main_iteration = kwargs.get('main_iteration', True) - return RPCProgress('execute', args).run(process_exception, main_iteration) + callback = kwargs.get('callback') + return RPCProgress('execute', args).run(process_exception, callback) + + +def RPCContextReload(callback=None): + def update(context): + rpc.CONTEXT.clear() + rpc.CONTEXT.update(context()) + if callback: + callback() + RPCExecute('model', 'res.user', 'get_preferences', True, callback=update) class Tooltips(object): diff --git a/tryton/common/completion.py b/tryton/common/completion.py index 441d422fdd..307b68ecf9 100644 --- a/tryton/common/completion.py +++ b/tryton/common/completion.py @@ -39,20 +39,23 @@ def update_completion(entry, record, field, model, domain=None): domain = field.domain_get(record) context = field.context_get(record) domain = [('rec_name', 'ilike', '%' + search_text + '%'), domain] - try: - results = RPCExecute('model', model, 'search_read', domain, 0, - CONFIG['client.limit'], None, ['rec_name'], context=context, - process_exception=False) - except (TrytonError, TrytonServerError): - results = [] - if search_text != entry.get_text().decode('utf-8'): - return False - completion_model.clear() - for result in results: - completion_model.append([result['rec_name'], result['id']]) - completion_model.search_text = search_text - # Force display of popup - entry.emit('changed') + + def callback(results): + try: + results = results() + except (TrytonError, TrytonServerError): + results = [] + if search_text != entry.get_text().decode('utf-8'): + return False + completion_model.clear() + for result in results: + completion_model.append([result['rec_name'], result['id']]) + completion_model.search_text = search_text + # Force display of popup + entry.emit('changed') + RPCExecute('model', model, 'search_read', domain, 0, + CONFIG['client.limit'], None, ['rec_name'], context=context, + process_exception=False, callback=callback) return False search_text = entry.get_text().decode('utf-8') gobject.timeout_add(300, update, search_text, domain) diff --git a/tryton/common/popup_menu.py b/tryton/common/popup_menu.py index 4b4e743c1c..6743b7b0f1 100644 --- a/tryton/common/popup_menu.py +++ b/tryton/common/popup_menu.py @@ -23,10 +23,6 @@ def populate(menu, model, record, title=''): return elif record.id < 0: return - try: - toolbar = RPCExecute('model', model, 'view_toolbar_get') - except RPCException: - return def load(record): if isinstance(record, (int, long)): @@ -72,31 +68,37 @@ def populate(menu, model, record, title=''): action_menu.append(attachment_item) attachment_item.connect('activate', attachment) - for atype, icon, label, flavor in ( - ('action', 'tryton-executable', _('Actions...'), None), - ('relate', 'tryton-go-jump', _('Relate...'), None), - ('print', 'tryton-print-open', _('Report...'), 'open'), - ('print', 'tryton-print-email', _('E-Mail...'), 'email'), - ('print', 'tryton-print', _('Print...'), 'print'), - ): - if len(action_menu): - action_menu.append(gtk.SeparatorMenuItem()) - title_item = gtk.ImageMenuItem(icon) - title_item.set_label(label) - action_menu.append(title_item) - if not toolbar[atype]: - title_item.set_sensitive(False) - continue - submenu = gtk.Menu() - title_item.set_submenu(submenu) - for action in toolbar[atype]: - action = action.copy() - item = gtk.MenuItem(action['name']) - submenu.append(item) - if flavor == 'print': - action['direct_print'] = True - elif flavor == 'email': - action['email_print'] = True - item.connect('activate', activate, action, atype) - + def set_toolbar(toolbar): + try: + toolbar = toolbar() + except RPCException: + return + for atype, icon, label, flavor in ( + ('action', 'tryton-executable', _('Actions...'), None), + ('relate', 'tryton-go-jump', _('Relate...'), None), + ('print', 'tryton-print-open', _('Report...'), 'open'), + ('print', 'tryton-print-email', _('E-Mail...'), 'email'), + ('print', 'tryton-print', _('Print...'), 'print'), + ): + if len(action_menu): + action_menu.append(gtk.SeparatorMenuItem()) + title_item = gtk.ImageMenuItem(icon) + title_item.set_label(label) + action_menu.append(title_item) + if not toolbar[atype]: + title_item.set_sensitive(False) + continue + submenu = gtk.Menu() + title_item.set_submenu(submenu) + for action in toolbar[atype]: + action = action.copy() + item = gtk.MenuItem(action['name']) + submenu.append(item) + if flavor == 'print': + action['direct_print'] = True + elif flavor == 'email': + action['email_print'] = True + item.connect('activate', activate, action, atype) + menu.show_all() + RPCExecute('model', model, 'view_toolbar_get', callback=set_toolbar) menu.show_all() diff --git a/tryton/gui/main.py b/tryton/gui/main.py index d0106e7448..bb7997a434 100644 --- a/tryton/gui/main.py +++ b/tryton/gui/main.py @@ -16,7 +16,7 @@ import webbrowser import threading import tryton.rpc as rpc -from tryton.common import RPCExecute, RPCException +from tryton.common import RPCExecute, RPCException, RPCContextReload from tryton.config import CONFIG, TRYTON_ICON, get_config_dir import tryton.common as common from tryton.pyson import PYSONDecoder @@ -325,31 +325,35 @@ class Main(object): return False if getattr(gmodel, 'search_text', None) == search_text: return False - try: - result = RPCExecute('model', 'ir.model', 'global_search', + + def callback(result): + try: + result = result() + except RPCException: + result = [] + if search_text != widget.get_text().decode('utf-8'): + return False + gmodel.clear() + for r in result: + _, model, model_name, record_id, record_name, icon = r + if icon: + text = common.to_xml(record_name) + common.ICONFACTORY.register_icon(icon) + pixbuf = widget.render_icon(stock_id=icon, + size=gtk.ICON_SIZE_BUTTON, detail=None) + else: + text = '%s:\n %s' % ( + common.to_xml(model_name), + common.to_xml(record_name)) + pixbuf = None + gmodel.append([pixbuf, text, model, record_id]) + gmodel.search_text = search_text + # Force display of popup + widget.emit('changed') + + RPCExecute('model', 'ir.model', 'global_search', search_text, CONFIG['client.limit'], - self.menu_screen.model_name) - except RPCException: - result = [] - if search_text != widget.get_text().decode('utf-8'): - return False - gmodel.clear() - for r in result: - _, model, model_name, record_id, record_name, icon = r - if icon: - text = common.to_xml(record_name) - common.ICONFACTORY.register_icon(icon) - pixbuf = widget.render_icon(stock_id=icon, - size=gtk.ICON_SIZE_BUTTON, detail=None) - else: - text = '%s:\n %s' % ( - common.to_xml(model_name), - common.to_xml(record_name)) - pixbuf = None - gmodel.append([pixbuf, text, model, record_id]) - gmodel.search_text = search_text - # Force display of popup - widget.emit('changed') + self.menu_screen.model_name, callback=callback) return False def changed(widget): @@ -842,38 +846,43 @@ class Main(object): self.notebook.set_current_page(page - 1) def get_preferences(self): - rpc.context_reload() - try: - prefs = RPCExecute('model', 'res.user', 'get_preferences', - False) - except RPCException: - prefs = {} - threads = [] - for target in ( - common.ICONFACTORY.load_icons, - common.MODELACCESS.load_models, - common.VIEW_SEARCH.load_searches, - ): - t = threading.Thread(target=target) - threads.append(t) - t.start() - for t in threads: - t.join() - if prefs and 'language_direction' in prefs: - translate.set_language_direction(prefs['language_direction']) - CONFIG['client.language_direction'] = \ - prefs['language_direction'] - self.sig_win_menu(prefs=prefs) - for action_id in prefs.get('actions', []): - Action.execute(action_id, {}) - self.set_title(prefs.get('status_bar', '')) - if prefs and 'language' in prefs: - translate.setlang(prefs['language'], prefs.get('locale')) - if CONFIG['client.lang'] != prefs['language']: - self.set_menubar() - self.favorite_unset() - CONFIG['client.lang'] = prefs['language'] - CONFIG.save() + def _set_preferences(prefs): + try: + prefs = prefs() + except RPCException: + prefs = {} + threads = [] + for target in ( + common.ICONFACTORY.load_icons, + common.MODELACCESS.load_models, + common.VIEW_SEARCH.load_searches, + ): + t = threading.Thread(target=target) + threads.append(t) + t.start() + for t in threads: + t.join() + if prefs and 'language_direction' in prefs: + translate.set_language_direction(prefs['language_direction']) + CONFIG['client.language_direction'] = \ + prefs['language_direction'] + self.sig_win_menu(prefs=prefs) + for action_id in prefs.get('actions', []): + Action.execute(action_id, {}) + self.set_title(prefs.get('status_bar', '')) + if prefs and 'language' in prefs: + translate.setlang(prefs['language'], prefs.get('locale')) + if CONFIG['client.lang'] != prefs['language']: + self.set_menubar() + self.favorite_unset() + CONFIG['client.lang'] = prefs['language'] + CONFIG.save() + + def _get_preferences(): + RPCExecute('model', 'res.user', 'get_preferences', False, + callback=_set_preferences) + + RPCContextReload(_get_preferences) def sig_user_preferences(self, widget): if not self.close_pages(): diff --git a/tryton/gui/window/view_form/model/field.py b/tryton/gui/window/view_form/model/field.py index 82eaa32170..e3bc13a16a 100644 --- a/tryton/gui/window/view_form/model/field.py +++ b/tryton/gui/window/view_form/model/field.py @@ -410,7 +410,7 @@ class M2OField(CharField): if not rec_name and value >= 0: try: result, = RPCExecute('model', self.attrs['relation'], 'read', - [value], ['rec_name'], main_iteration=False) + [value], ['rec_name']) except RPCException: return False rec_name = result['rec_name'] or '' @@ -603,8 +603,7 @@ class O2MField(CharField): if field_names: try: fields.update(RPCExecute('model', self.attrs['relation'], - 'fields_get', list(field_names), - main_iteration=False, context=context)) + 'fields_get', list(field_names), context=context)) except RPCException: return @@ -681,8 +680,7 @@ class O2MField(CharField): if field_names: try: fields = RPCExecute('model', self.attrs['relation'], - 'fields_get', list(field_names), main_iteration=False, - context=context) + 'fields_get', list(field_names), context=context) except RPCException: return False else: @@ -855,7 +853,7 @@ class ReferenceField(CharField): if not rec_name and ref_id >= 0: try: result, = RPCExecute('model', ref_model, 'read', [ref_id], - ['rec_name'], main_iteration=False) + ['rec_name']) except RPCException: return rec_name = result['rec_name'] @@ -910,8 +908,7 @@ class BinaryField(CharField): context = record.context_get() try: values, = RPCExecute('model', record.model_name, 'read', - [record.id], [self.name], main_iteration=False, - context=context) + [record.id], [self.name], context=context) except RPCException: return '' _, filename = tempfile.mkstemp(prefix='tryton_') diff --git a/tryton/gui/window/view_form/model/group.py b/tryton/gui/window/view_form/model/group.py index 15861205c7..645de68219 100644 --- a/tryton/gui/window/view_form/model/group.py +++ b/tryton/gui/window/view_form/model/group.py @@ -203,7 +203,7 @@ class Group(SignalEvent, list): for fnct in self.on_write: try: res += RPCExecute('model', self.model_name, fnct, ids, - main_iteration=False, context=self.context) + context=self.context) except RPCException: return [] return list({}.fromkeys(res)) @@ -392,7 +392,7 @@ class Group(SignalEvent, list): if len(new) and len(to_add): try: values = RPCExecute('model', self.model_name, 'default_get', - to_add.keys(), main_iteration=False, context=self.context) + to_add.keys(), context=self.context) except RPCException: return False for record in new: diff --git a/tryton/gui/window/view_form/model/record.py b/tryton/gui/window/view_form/model/record.py index 208a1759c1..ad1914290c 100644 --- a/tryton/gui/window/view_form/model/record.py +++ b/tryton/gui/window/view_form/model/record.py @@ -118,8 +118,7 @@ class Record(SignalEvent): exception = None try: values = RPCExecute('model', self.model_name, 'read', - id2record.keys(), fnames, context=ctx, - main_iteration=False) + id2record.keys(), fnames, context=ctx) except RPCException, exception: values = [{'id': x} for x in id2record] default_values = dict((f, None) for f in fnames) @@ -286,7 +285,7 @@ class Record(SignalEvent): values = self._get_on_change_args(self.modified_fields) try: RPCExecute('model', self.model_name, 'pre_validate', values, - main_iteration=False, context=self.context_get()) + context=self.context_get()) except RPCException: return False return True @@ -297,8 +296,7 @@ class Record(SignalEvent): value = self.get() try: res, = RPCExecute('model', self.model_name, 'create', - [value], main_iteration=False, - context=self.context_get()) + [value], context=self.context_get()) except RPCException: return False old_id = self.id @@ -312,8 +310,7 @@ class Record(SignalEvent): context['_timestamp'] = self.get_timestamp() try: RPCExecute('model', self.model_name, 'write', - [self.id], value, main_iteration=False, - context=context) + [self.id], value, context=context) except RPCException: return False self._loaded.clear() @@ -346,7 +343,7 @@ class Record(SignalEvent): reload_ids = list(reload_ids) try: RPCExecute('model', record.model_name, 'delete', list(record_ids), - main_iteration=False, context=ctx) + context=ctx) except RPCException: return False if reload_ids: @@ -357,8 +354,7 @@ class Record(SignalEvent): if len(self.group.fields): try: vals = RPCExecute('model', self.model_name, 'default_get', - self.group.fields.keys(), main_iteration=False, - context=self.context_get()) + self.group.fields.keys(), context=self.context_get()) except RPCException: return if (self.parent @@ -380,8 +376,7 @@ class Record(SignalEvent): def rec_name(self): try: return RPCExecute('model', self.model_name, 'read', [self.id], - ['rec_name'], main_iteration=False, - context=self.context_get())[0]['rec_name'] + ['rec_name'], context=self.context_get())[0]['rec_name'] except RPCException: return '' @@ -532,8 +527,7 @@ class Record(SignalEvent): args = self._get_on_change_args(attr) try: res = RPCExecute('model', self.model_name, 'on_change_' + - fieldname, args, main_iteration=False, - context=self.context_get()) + fieldname, args, context=self.context_get()) except RPCException: return self.set_on_change(res) @@ -564,8 +558,7 @@ class Record(SignalEvent): if fieldnames: try: result = RPCExecute('model', self.model_name, 'on_change_with', - values, list(fieldnames), main_iteration=False, - context=self.context_get()) + values, list(fieldnames), context=self.context_get()) except RPCException: return self.set_on_change(result) @@ -576,7 +569,7 @@ class Record(SignalEvent): try: result = RPCExecute('model', self.model_name, 'on_change_with_' + fieldname, values, - main_iteration=False, context=self.context_get()) + context=self.context_get()) except RPCException: return self.group.fields[fieldname].set_on_change(self, result) @@ -594,8 +587,7 @@ class Record(SignalEvent): args = self._get_on_change_args(autocomplete) try: res = RPCExecute('model', self.model_name, 'autocomplete_' + - fieldname, args, main_iteration=False, - context=self.context_get()) + fieldname, args, context=self.context_get()) except RPCException: # ensure res is a list res = [] @@ -610,7 +602,7 @@ class Record(SignalEvent): 'search_count', [ ('resource', '=', '%s,%s' % (self.model_name, self.id)), - ], main_iteration=False) + ]) except RPCException: return 0 return self.attachment_count diff --git a/tryton/gui/window/wizard.py b/tryton/gui/window/wizard.py index c76664acf5..9a22c60216 100644 --- a/tryton/gui/window/wizard.py +++ b/tryton/gui/window/wizard.py @@ -3,17 +3,16 @@ import gtk import pango import gettext -import socket from tryton.signal_event import SignalEvent -import tryton.rpc as rpc import tryton.common as common from tryton.gui.window.view_form.screen import Screen from tryton.gui import Main -from tryton.exceptions import TrytonServerError, TrytonServerUnavailable +from tryton.exceptions import TrytonServerError from tryton.gui.window.nomodal import NoModal from tryton.common.button import Button -from tryton.common import RPCExecute, RPCException, TRYTON_ICON +from tryton.common import RPCExecute, RPCException, RPCContextReload +from tryton.common import TRYTON_ICON _ = gettext.gettext @@ -55,83 +54,85 @@ class Wizard(object): self.email_print = email_print self.email = email self.context = context - try: - result = RPCExecute('wizard', action, 'create') - except RPCException: - return - self.session_id, self.start_state, self.end_state = result - self.state = self.start_state - self.process() + + def callback(result): + try: + result = result() + except RPCException: + return + self.session_id, self.start_state, self.end_state = result + self.state = self.start_state + self.process() + RPCExecute('wizard', action, 'create', callback=callback) def process(self): from tryton.action import Action if self.__processing or self.__waiting_response: return - try: - self.__processing = True - while self.state != self.end_state: - ctx = self.context.copy() - ctx['active_id'] = self.id - ctx['active_ids'] = self.ids - ctx['active_model'] = self.model - ctx['action_id'] = self.action_id - if self.screen: - data = { - self.screen_state: self.screen.get_on_change_value(), - } - else: - data = {} - try: - result = RPCExecute('wizard', self.action, 'execute', - self.session_id, data, self.state, context=ctx) - except RPCException, rpc_exception: - if (not isinstance(rpc_exception.exception, - TrytonServerError) - or not self.screen): - self.state = self.end_state - break + self.__processing = True - if 'view' in result: - self.clean() - view = result['view'] - self.update(view['fields_view'], view['defaults'], - view['buttons']) - self.screen_state = view['state'] - self.__waiting_response = True - else: + ctx = self.context.copy() + ctx['active_id'] = self.id + ctx['active_ids'] = self.ids + ctx['active_model'] = self.model + ctx['action_id'] = self.action_id + if self.screen: + data = { + self.screen_state: self.screen.get_on_change_value(), + } + else: + data = {} + + def callback(result): + try: + result = result() + except RPCException, rpc_exception: + if (not isinstance(rpc_exception.exception, + TrytonServerError) + or not self.screen): self.state = self.end_state + self.end() + self.__processing = False + return - if 'actions' in result: - sensitive_widget = self.widget.get_toplevel() - if not 'view' in result: - self.end() - for action in result['actions']: - Action._exec_action(*action, context=ctx) - if (not 'view' in result - or (action[0]['type'] == 'ir.action.wizard' - and not sensitive_widget.props.sensitive)): - return - if self.__waiting_response: - break + if 'view' in result: + self.clean() + view = result['view'] + self.update(view['fields_view'], view['defaults'], + view['buttons']) + self.screen_state = view['state'] + self.__waiting_response = True + else: + self.state = self.end_state + + if 'actions' in result: + sensitive_widget = self.widget.get_toplevel() + if not 'view' in result: + self.end() + for action in result['actions']: + Action._exec_action(*action, context=ctx) + if (not 'view' in result + or (action[0]['type'] == 'ir.action.wizard' + and not sensitive_widget.props.sensitive)): + self.__processing = False + return if self.state == self.end_state: self.end() - finally: self.__processing = False + RPCExecute('wizard', self.action, 'execute', self.session_id, data, + self.state, context=ctx, callback=callback) + def destroy(self): if self.screen: self.screen.destroy() - def end(self): - try: - return RPCExecute('wizard', self.action, 'delete', self.session_id, - process_exception=False) - if self.action == 'ir.module.module.config_wizard': - rpc.context_reload() - Main.get_main().sig_win_menu() - except (TrytonServerError, socket.error, TrytonServerUnavailable): - pass + def end(self, callback=None): + RPCExecute('wizard', self.action, 'delete', self.session_id, + process_exception=False, callback=callback) + if self.action == 'ir.module.module.config_wizard': + RPCContextReload(Main.get_main().sig_win_menu) def clean(self): for widget in self.widget.get_children(): @@ -360,8 +361,9 @@ class WizardDialog(Wizard, NoModal): dialog.screen.client_action(action) def end(self): - action = super(WizardDialog, self).end() - self.destroy(action=action) + def callback(action): + self.destroy(action=action()) + super(WizardDialog, self).end(callback=callback) def close(self, widget, event=None): if self.end_state in self.states: diff --git a/tryton/rpc.py b/tryton/rpc.py index 555dd7b927..b0af1a44f4 100644 --- a/tryton/rpc.py +++ b/tryton/rpc.py @@ -130,16 +130,6 @@ def logout(): _KEYWORD_CACHE = {} -def context_reload(): - global CONTEXT - try: - context = execute('model', 'res.user', 'get_preferences', True, {}) - except Fault: - return - CONTEXT = {} - CONTEXT.update(context) - - def _execute(blocking, *args): global CONNECTION, _USER, _SESSION if CONNECTION is None: