Manage selection tree state

review823002
This commit is contained in:
Cédric Krier committed 2013-08-01 17:09:47 +02:00
1 parent 982654446a
commit 7b4c2e97b5
8 files changed
+80 -38

No files matched your search

+1 -1
View File
@@ -57,7 +57,7 @@ class ConfigManager(object):
'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],
+4 -4
View File
@@ -610,15 +610,15 @@ class Main(object):
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:
+3 -3
View File
@@ -8,8 +8,8 @@ from tryton.gui.window.win_form import WinForm
class Attachment(WinForm):
"Attachment window"
def __init__(self, model_name, record_id, callback=None):
self.resource = '%s,%s' % (model_name, record_id)
def __init__(self, record, callback=None):
self.resource = '%s,%s' % (record.model_name, record.id)
self.attachment_callback = callback
screen = Screen('ir.attachment', domain=[
('resource', '=', self.resource),
@@ -17,7 +17,7 @@ class Attachment(WinForm):
'resource': self.resource,
}, exclude_field='resource')
screen.search_filter()
screen.parent = True
screen.parent = record
super(Attachment, self).__init__(screen, self.callback,
view_type='tree')
+3 -3
View File
@@ -201,10 +201,10 @@ class Form(SignalEvent, TabContent):
return self.screen.id_get()
def sig_attach(self, widget=None):
record_id = self.id_get()
if record_id is False or record_id < 0:
record = self.screen.current_record
if not record or record.id < 0:
return
Attachment(self.model, record_id,
Attachment(record,
lambda: self.update_attachment_count(reload=True))
def update_attachment_count(self, reload=False):
+34 -17
View File
@@ -14,6 +14,7 @@ import urllib
import urlparse
import xml.dom.minidom
import gettext
import logging
from tryton.gui.window.view_form.model.group import Group
from tryton.gui.window.view_form.model.record import Record
@@ -88,8 +89,9 @@ class Screen(SignalEvent):
self.fields_view_tree = None
self.order = order
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[:]
@@ -611,29 +613,39 @@ class Screen(SignalEvent):
def set_tree_state(self):
view = self.current_view
if (not CONFIG['client.save_tree_expanded_state']
or not self.current_view
or self.current_view.view_type != 'tree'
or not self.current_view.children_field
if (not CONFIG['client.save_tree_state']
or not view
or view.view_type != 'tree'
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:
logging.getLogger(__name__).warn(
_('Unable to get view tree state'))
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, store=True):
if not CONFIG['client.save_tree_expanded_state']:
if not CONFIG['client.save_tree_state']:
return
for view in self.views:
if view.view_type == 'form':
@@ -644,17 +656,21 @@ class Screen(SignalEvent):
elif (view.view_type == 'tree' and view.children_field):
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)
if store:
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,
view.children_field, json_paths,
RPCExecute('model', 'ir.ui.view_tree_state', 'set',
self.model_name, json_domain, view.children_field,
json_paths, json_selected_path,
process_exception=False)
except (TrytonServerError, TrytonServerUnavailable):
pass
logging.getLogger(__name__).warn(
_('Unable to set view tree state'))
def get_tree_domain(self, parent):
if parent:
@@ -665,7 +681,8 @@ class Screen(SignalEvent):
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:
+33 -3
View File
@@ -750,8 +750,7 @@ class ViewList(ParserView):
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
@@ -862,7 +861,11 @@ class ViewList(ParserView):
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):
@@ -896,6 +899,33 @@ class ViewList(ParserView):
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
@@ -108,7 +108,6 @@ class ParserTree(ParserInterface):
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 @@ class ParserTree(ParserInterface):
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):
+2
View File
@@ -58,6 +58,8 @@ class WinSearch(NoModal):
row_activate=self.sig_activate)
self.view = self.screen.current_view
self.view.unset_editable()
# Prevent to set tree_state
self.screen.tree_states_done.add(id(self.view))
sel = self.view.widget_tree.get_selection()
if not sel_multi: