Reviewers: ,


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

Affected files:
  M tryton/gui/window/view_form/view/form.py


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

--- a/tryton/gui/window/view_form/view/form.py
+++ b/tryton/gui/window/view_form/view/form.py
@@ -9,6 +9,68 @@
 _ = gettext.gettext
 
 
+def get_invisible_ancestor(widget):
+    if not widget.get_visible():
+        return widget
+    if not widget.parent:
+        return None
+    return get_invisible_ancestor(widget.parent)
+
+
+def find_focused_widget(widget):
+    if widget.has_focus():
+        return widget
+    if not hasattr(widget, 'get_children'):
+        return None
+    for child in widget.get_children():
+        focused_widget = find_focused_widget(child)
+        if focused_widget:
+            return focused_widget
+
+
+def find_focusable_widget(widget):
+    if widget.get_can_focus() and widget.get_visible():
+        return widget
+    if not hasattr(widget, 'get_children'):
+        return None
+    focus_chain = widget.get_focus_chain()
+    widgets = (focus_chain
+        if focus_chain is not None
+        else widget.get_children())
+    for child in widgets:
+        focusable = find_focusable_widget(child)
+        if focusable:
+            return focusable
+
+
+def next_focus_widget(widget):
+    if not widget.parent:
+        return None
+    focus_chain = widget.parent.get_focus_chain()
+    if focus_chain is not None:
+        idx = focus_chain.index(widget)
+        focus_widget = None
+        for offset in range(1, len(focus_chain)):
+            if idx + offset < len(focus_chain):
+                next_widget = focus_chain[idx + offset]
+                focus_widget = find_focusable_widget(next_widget)
+            if idx - offset >= 0:
+                prev_widget = focus_chain[idx - offset]
+                focus_widget = find_focusable_widget(prev_widget)
+            if focus_widget:
+                break
+        if focus_widget:
+            return focus_widget
+        else:
+            return next_focus_widget(widget.parent)
+    else:
+        focus_widget = find_focusable_widget(widget.parent)
+        if focus_widget:
+            return focus_widget
+        else:
+            return next_focus_widget(widget.parent)
+
+
 class ViewForm(ParserView):
 
     def __init__(self, screen, widget, children=None, state_widgets=None,
@@ -119,6 +181,7 @@
             fields.sort(key=operator.itemgetter(1), reverse=True)
             for field, _ in fields:
                 record[field].get(record)
+        focused_widget = find_focused_widget(self.widget)
         for name, widgets in self.widgets.iteritems():
             field = None
             if record:
@@ -129,6 +192,12 @@
                 widget.display(record, field)
         for widget in self.state_widgets:
             widget.state_set(record)
+        if focused_widget:
+            invisible_ancestor = get_invisible_ancestor(focused_widget)
+            if invisible_ancestor:
+                new_focused_widget = next_focus_widget(invisible_ancestor)
+                if new_focused_widget:
+                    new_focused_widget.grab_focus()
         return True
 
     def set_cursor(self, new=False, reset_view=True):

Reply via email to