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):