Reviewers: ,


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

Affected files:
  M tryton/config.py
  M tryton/gui/main.py
  M tryton/gui/window/view_form/screen/screen.py
  M tryton/gui/window/view_form/view/list.py
  M tryton/gui/window/view_form/view/list_gtk/parser.py
  M tryton/gui/window/win_search.py


Index: tryton/config.py
===================================================================

--- a/tryton/config.py
+++ b/tryton/config.py
@@ -58,7 +58,7 @@
             'client.form_tab': form_tab,
             'client.maximize': False,
             'client.save_width_height': True,
-            'client.save_tree_expanded_state': True,
+            'client.save_tree_state': True,
             'client.spellcheck': False,
             'client.default_path': get_home_dir(),
             'client.lang': locale.getdefaultlocale()[0],

Index: tryton/gui/main.py
===================================================================

--- a/tryton/gui/main.py
+++ b/tryton/gui/main.py
@@ -668,15 +668,15 @@
             checkmenuitem_save_width_height.set_active(True)

         checkmenuitem_save_tree_state = gtk.CheckMenuItem(
-            _('Save Tree Expanded State'))
+            _('Save Tree State'))
         checkmenuitem_save_tree_state.connect('activate',
             lambda menuitem: CONFIG.__setitem__(
-                'client.save_tree_expanded_state',
+                'client.save_tree_state',
                 menuitem.get_active()))
         checkmenuitem_save_tree_state.set_accel_path(
-            '<tryton>/Options/Form/Save Tree Expanded State')
+            '<tryton>/Options/Form/Save Tree State')
         menu_form.add(checkmenuitem_save_tree_state)
-        if CONFIG['client.save_tree_expanded_state']:
+        if CONFIG['client.save_tree_state']:
             checkmenuitem_save_tree_state.set_active(True)

         if gtkspell:

Index: tryton/gui/window/view_form/screen/screen.py
===================================================================

--- a/tryton/gui/window/view_form/screen/screen.py
+++ b/tryton/gui/window/view_form/screen/screen.py
@@ -83,8 +83,9 @@
         self.fields_view_tree = None
         self.sort = sort
         self.view_to_load = []
-        self.expanded_nodes = collections.defaultdict(
+        self.tree_states = collections.defaultdict(
             lambda: collections.defaultdict(lambda: None))
+        self.tree_states_done = set()
         self.domain_parser = None
         self.pre_validate = False
         self.view_to_load = mode[:]
@@ -598,46 +599,54 @@

     def set_tree_state(self):
         view = self.current_view
-        if (not CONFIG['client.save_tree_expanded_state']
+        if (not CONFIG['client.save_tree_state']
                 or not self.current_view
                 or self.current_view.view_type != 'tree'
-                or not self.current_view.children_field
                 or not self.group):
             return
+        if id(view) in self.tree_states_done:
+            return
         parent = self.parent.id if self.parent else None
-        expanded_nodes = self.expanded_nodes[parent][view.children_field]
-        if expanded_nodes is None:
+        state = self.tree_states[parent][view.children_field]
+        if state is None:
             json_domain = self.get_tree_domain(parent)
             try:
-                expanded_nodes = RPCExecute('model',
-                    'ir.ui.view_tree_expanded_state', 'get_expanded',
+                expanded_nodes, selected_nodes = RPCExecute('model',
+                    'ir.ui.view_tree_state', 'get',
                     self.model_name, json_domain,
                     self.current_view.children_field)
                 expanded_nodes = json.loads(expanded_nodes)
+                selected_nodes = json.loads(selected_nodes)
             except RPCException:
                 expanded_nodes = []
- self.expanded_nodes[parent][view.children_field] = expanded_nodes
+                selected_nodes = []
+            self.tree_states[parent][view.children_field] = (
+                expanded_nodes, selected_nodes)
+        else:
+            expanded_nodes, selected_nodes = state
         view.expand_nodes(expanded_nodes)
+        view.select_nodes(selected_nodes)
+        self.tree_states_done.add(id(view))

     def save_tree_state(self):
         view = self.current_view
-        if (not CONFIG['client.save_tree_expanded_state']
+        if (not CONFIG['client.save_tree_state']
                 or not view
                 or view.view_type != 'tree'
-                or not view.children_field
                 or not (self.parent is None
                     or isinstance(self.parent, Record))):
             return
         parent = self.parent.id if self.parent else None
         paths = view.get_expanded_paths()
-        self.expanded_nodes[parent][view.children_field] = paths
+        selected_paths = view.get_selected_paths()
+ self.tree_states[parent][view.children_field] = (paths, selected_paths)
         json_domain = self.get_tree_domain(parent)
         json_paths = json.dumps(paths)
+        json_selected_path = json.dumps(selected_paths)
         try:
-            RPCExecute('model', 'ir.ui.view_tree_expanded_state',
-                'set_expanded', self.model_name, json_domain,
-                self.current_view.children_field, json_paths,
-                process_exception=False)
+            RPCExecute('model', 'ir.ui.view_tree_state', 'set',
+ self.model_name, json_domain, self.current_view.children_field,
+                json_paths, json_selected_path, process_exception=False)
         except (TrytonServerError, TrytonServerUnavailable):
             pass

@@ -650,7 +659,8 @@
         return json_domain

     def load(self, ids, set_cursor=True, modified=False):
-        self.expanded_nodes.clear()
+        self.tree_states.clear()
+        self.tree_states_done.clear()
         self.group.load(ids, modified=modified)
         self.current_view.reset()
         if ids:

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

--- a/tryton/gui/window/view_form/view/list.py
+++ b/tryton/gui/window/view_form/view/list.py
@@ -752,8 +752,7 @@
         elif tree_sel.get_mode() == gtk.SELECTION_MULTIPLE:
             model, paths = tree_sel.get_selected_rows()
             if model and paths:
-                iter_ = model.get_iter(paths[0])
-                record = model.get_value(iter_, 0)
+                record = model.on_get_iter(paths[0])
                 self.screen.current_record = record
             else:
                 self.screen.current_record = None
@@ -864,7 +863,11 @@
                 self.widget_tree.expand_to_path(path[:-1])
             self.widget_tree.scroll_to_cell(path, focus_column,
                 use_align=False)
-            self.widget_tree.set_cursor(path, focus_column, new)
+            current_path = self.widget_tree.get_cursor()[0]
+            selected_path = \
+                self.widget_tree.get_selection().get_selected_rows()[1]
+            if (current_path != path and path not in selected_path) or new:
+                self.widget_tree.set_cursor(path, focus_column, new)

     def sel_ids_get(self):
         def _func_sel_get(store, path, iter, ids):
@@ -898,6 +901,33 @@
                 else:
                     renderer.set_property('editable', False)

+    def get_selected_paths(self):
+        selection = self.widget_tree.get_selection()
+        model, rows = selection.get_selected_rows()
+        id_paths = []
+        for row in rows:
+            path = ()
+            id_path = []
+            for node in row:
+                path += (node,)
+                id_path.append(model.on_get_iter(path).id)
+            id_paths.append(id_path)
+        return id_paths
+
+    def select_nodes(self, nodes):
+        selection = self.widget_tree.get_selection()
+        if not nodes:
+            return
+        selection.unselect_all()
+        scroll = False
+        for node in nodes:
+            path = path_convert_id2pos(self.store, node)
+            if path:
+                selection.select_path(path)
+                if not scroll:
+                    self.widget_tree.scroll_to_cell(path)
+                    scroll = True
+
def get_expanded_paths(self, starting_path=None, starting_id_path=None):
         # Use id instead of position
         # because the position may change between load

Index: tryton/gui/window/view_form/view/list_gtk/parser.py
===================================================================

--- a/tryton/gui/window/view_form/view/list_gtk/parser.py
+++ b/tryton/gui/window/view_form/view/list_gtk/parser.py
@@ -108,7 +108,6 @@
         treeview.sequence = attrs.get('sequence', False)
         treeview.colors = attrs.get('colors', '"black"')
         treeview.keyword_open = attrs.get('keyword_open', False)
-        treeview.connect('focus', self.set_selection)
         self.treeview = treeview
         treeview.set_property('rules-hint', True)
         if not self.title:
@@ -296,12 +295,6 @@
         treeview.set_fixed_height_mode(True)
         return treeview, dict_widget, state_widgets, on_write, [], None

-    def set_selection(self, treeview, direction):
-        selection = treeview.get_selection()
- if len(treeview.get_model()) and not selection.count_selected_rows():
-            selection.select_path(0)
-        return False
-

 class Affix(object):


Index: tryton/gui/window/win_search.py
===================================================================

--- a/tryton/gui/window/win_search.py
+++ b/tryton/gui/window/win_search.py
@@ -56,6 +56,7 @@
         self.screen = Screen(model, domain=domain, mode=['tree'],
context=context, view_ids=view_ids, views_preload=views_preload,
             row_activate=self.sig_activate)
+        # TODO fix tree_state
         self.view = self.screen.current_view
         self.view.unset_editable()
         sel = self.view.widget_tree.get_selection()



Reply via email to