Fix focus of invalid widget

tab_compare only works correctly for sibling widgets. find_first_focus_widget
uses the nested focus_chain to find the first widget.

issue4332
review5741002
This commit is contained in:
Cédric Krier committed 2014-11-19 21:21:38 +01:00
1 parent 5542d95814
commit 5b7c2ff067
2 files changed
+21 -12

No files matched your search

+18 -7
View File
@@ -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)
+3 -5
View File
@@ -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()):