diff --git a/tryton/common/focus.py b/tryton/common/focus.py index 9d54df1eab..1afcd3c072 100644 --- a/tryton/common/focus.py +++ b/tryton/common/focus.py @@ -41,6 +41,15 @@ def tab_compare(a, b): return (y1 > y2) - (y1 < y2) +def get_focus_chain(widget): + focus_chain = widget.get_focus_chain() + # If the focus_chain is not defined on the widget then we will simply + # search into all its children widgets + return (focus_chain + if focus_chain is not None + else sorted(widget.get_children(), key=cmp_to_key(tab_compare))) + + def find_focusable_child(widget): if not widget.get_visible(): return None @@ -48,13 +57,7 @@ def find_focusable_child(widget): return widget if not hasattr(widget, 'get_children'): return None - focus_chain = widget.get_focus_chain() - # If the focus_chain is not defined on the widget then we will simply - # search into all its children widgets - widgets = (focus_chain - if focus_chain is not None - else sorted(widget.get_children(), key=cmp_to_key(tab_compare))) - for child in widgets: + for child in get_focus_chain(widget): focusable = find_focusable_child(child) if focusable: return focusable @@ -79,3 +82,11 @@ def next_focus_widget(widget): return focus_widget else: return next_focus_widget(widget.parent) + + +def find_first_focus_widget(ancestor, widgets): + "Return the widget from widgets which should have first the focus" + for child in get_focus_chain(ancestor): + common = [w for w in widgets if w.is_ancestor(child)] + if common: + return find_first_focus_widget(child, common) diff --git a/tryton/gui/window/view_form/view/form.py b/tryton/gui/window/view_form/view/form.py index a19e6b47d2..d8fcc2ce64 100644 --- a/tryton/gui/window/view_form/view/form.py +++ b/tryton/gui/window/view_form/view/form.py @@ -1,14 +1,13 @@ #This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. import operator -from functools import cmp_to_key import gtk import gettext from collections import defaultdict from . import View from tryton.common.focus import (get_invisible_ancestor, find_focused_child, - next_focus_widget, find_focusable_child, tab_compare) + next_focus_widget, find_focusable_child, find_first_focus_widget) from tryton.common import Tooltips, node_attributes, ICONFACTORY from tryton.common.button import Button from tryton.config import CONFIG @@ -501,9 +500,8 @@ class ViewForm(View): if not field.get_state_attrs(record).get('valid', True): invalid_widgets.append( find_focusable_child(widget.widget)) - invalid_widgets.sort(key=cmp_to_key(tab_compare)) - if invalid_widgets: - focus_widget = invalid_widgets[0] + focus_widget = find_first_focus_widget( + self._viewport, invalid_widgets) if focus_widget: for notebook in self.notebooks: for i in range(notebook.get_n_pages()):