Merge lp:~openerp-dev/openobject-client/trunk-m2o_with_selection-rga into lp:openobject-client

Proposed by Ravi Gadhia (OpenERP)
Status: Rejected
Rejected by: Naresh(OpenERP)
Proposed branch: lp:~openerp-dev/openobject-client/trunk-m2o_with_selection-rga
Merge into: lp:openobject-client
Diff against target: 579 lines (+169/-124)
9 files modified
bin/widget/model/field.py (+39/-9)
bin/widget/model/group.py (+4/-2)
bin/widget/model/record.py (+4/-0)
bin/widget/screen/screen.py (+0/-8)
bin/widget/view/form_gtk/selection.py (+46/-73)
bin/widget/view/list.py (+1/-1)
bin/widget/view/tree_gtk/editabletree.py (+7/-2)
bin/widget/view/tree_gtk/parser.py (+51/-24)
bin/widget_search/selection.py (+17/-5)
To merge this branch: bzr merge lp:~openerp-dev/openobject-client/trunk-m2o_with_selection-rga
Reviewer Review Type Date Requested Status
Naresh(OpenERP) Pending
Review via email: mp+58245@code.launchpad.net

This proposal supersedes a proposal from 2011-03-15.

Description of the change

Hello,

Improve selection field.

Now M2O field with widget="selection" no need to pre-load selection value (at time of fields_view_get) it's get value on popup by name_search and we can apply domain as like M2O field

related server branch:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-M2O_with_selection-rga

To post a comment you must log in.
Revision history for this message
Naresh(OpenERP) (nch-openerp) wrote : Posted in a previous version of this proposal

Hello,

For the client side stuff, there are few bugs I found.

1: The feature of search view "search_default_XXXX" in the context is not working causing a regression here with the above change.

2: setting value of the field which has widget="selection" thru an onchange does not work. Again a regression.

3:If a O2M has a subfield which has widget="selection" attribute behaves very odd

4:Once I have selected the value from the list that the name_search returns then on my next click the domain should take the text that is already selected in the field. currently it takes a ""(blank) value resulting in all records.

Thanks

review: Needs Resubmitting
Revision history for this message
Naresh(OpenERP) (nch-openerp) wrote :

will have to implement it with new spec like web(proto)

Unmerged revisions

1842. By Ravi Gadhia (OpenERP)

Merge with trunk client

1841. By Ravi Gadhia (OpenERP)

[IMP] search text should not clear even it's in selection list(model)

1840. By Ravi Gadhia (OpenERP)

[IMP] If selection field has not key:val then get it by rpc call

1839. By Ravi Gadhia (OpenERP)

[FIX] when widget=selection on one2many field's form view (where each time new modelfield created whid dialog box popup)

1838. By Ravi Gadhia (OpenERP)

[Fix] Search view: set default value on (M2O) widget=selection field

1837. By Ravi Gadhia (OpenERP)

Remove un-used variable

1836. By Ravi Gadhia (OpenERP)

[IMP] Editable list view: add context, domain on selection field

1835. By Ravi Gadhia (OpenERP)

[IMP] Editable list view: M2O field with selection make rpc call at the time of popup (no preloded selection data)

1834. By Ravi Gadhia (OpenERP)

[IMP]Form view: add context, domain on selection field + usability imrovement

1833. By Ravi Gadhia (OpenERP)

[IMP] Form view: m20 with selection widget make rpc call when combobox popup

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/widget/model/field.py'
2--- bin/widget/model/field.py 2011-04-13 13:24:05 +0000
3+++ bin/widget/model/field.py 2011-04-19 08:45:00 +0000
4@@ -45,12 +45,31 @@
5 klass = TYPES.get(type, CharField)
6 return klass
7
8+class M2O_SelectionField(dict):
9+ def __init__(self ,*args, **kwargs):
10+ self.swap = {}
11+
12+ def __setitem__(self, key, value):
13+ self.swap[value] = key
14+ super(M2O_SelectionField, self).__setitem__(key, value)
15+
16+ def update(self, *args, **kwargs):
17+ for key, val in args[0].items():
18+ self.swap[val] = key
19+ super(M2O_SelectionField, self).update(args[0])
20+
21+ def get_value(self, key):
22+ return self.get(key, '')
23+
24+ def get_key(self,value):
25+ return self.swap.get(value, False)
26
27 class CharField(object):
28 def __init__(self, parent, attrs):
29 self.parent = parent
30 self.attrs = attrs
31 self.name = attrs['name']
32+ self.selection = M2O_SelectionField()
33 self.internal = False
34 self.default_attrs = {}
35
36@@ -104,12 +123,12 @@
37 return True
38
39 def get(self, model, check_load=True, readonly=True, modified=False):
40- return model.value.get(self.name, False) or False
41+ return model.value.get(self.name, False)
42
43 def set_client(self, model, value, test_state=True, force_change=False):
44 internal = model.value.get(self.name, False)
45 self.set(model, value, test_state)
46- if (internal or False) != (model.value.get(self.name,False) or False):
47+ if (internal or False) != (model.value.get(self.name, False) or False):
48 model.modified = True
49 model.modified_fields.setdefault(self.name)
50 self.sig_changed(model)
51@@ -136,7 +155,7 @@
52 try:
53 attrs_changes = eval(self.attrs.get('attrs',"{}"))
54 except:
55- attrs_changes = eval(self.attrs.get('attrs',"{}"),model.value)
56+ attrs_changes = eval(self.attrs.get('attrs',"{}"), model.value)
57 for k,v in attrs_changes.items():
58 for i in range(0,len(v)):
59 if v[i][2]:
60@@ -242,14 +261,24 @@
61
62
63 class SelectionField(CharField):
64+
65+ def get(self, model, check_load=True, readonly=True, modified=False):
66+ return model.value.get(self.name, False)
67+
68 def set(self, model, value, test_state=True, modified=False):
69+ self.selection.update(dict(self.attrs.get('selection',[])))
70+
71+ if isinstance(value,(list,tuple)) and len(value):
72+ self.selection[value[0]] = value[1]
73+
74+ if value and isinstance(value, (int, long)) and self.attrs.get('relation', False):
75+ rpc2 = RPCProxy(self.attrs['relation'])
76+ result = rpc2.name_get([value], rpc.session.context)
77+ self.selection.update(dict(result))
78+
79 value = isinstance(value,(list,tuple)) and len(value) and value[0] or value
80-
81- if not self.get_state_attrs(model).get('required', False) and value is None:
82- super(SelectionField, self).set(model, value, test_state, modified)
83-
84- if value in [sel[0] for sel in self.attrs['selection']]:
85- super(SelectionField, self).set(model, value, test_state, modified)
86+
87+ super(SelectionField, self).set(model, value, test_state, modified)
88
89 class FloatField(CharField):
90 def validate(self, model):
91@@ -303,6 +332,7 @@
92 def get_client(self, model):
93 #model._check_load()
94 if model.value[self.name]:
95+ self.selection.update(dict([model.value[self.name]]))
96 return model.value[self.name][1]
97 return False
98
99
100=== modified file 'bin/widget/model/group.py'
101--- bin/widget/model/group.py 2011-04-13 05:28:58 +0000
102+++ bin/widget/model/group.py 2011-04-19 08:45:00 +0000
103@@ -343,7 +343,10 @@
104 for f in fields.keys():
105 add_field = True
106 if f in models.fields:
107- if fields[f].get('widget','') == models.fields[f].get('widget',''):
108+ if fields[f].get('widget','') == models.fields[f].get('widget','') :
109+ if fields[f].get('widget','') == 'selection' and models.mfields[f].selection:
110+ selection = models.mfields[f].selection
111+ fields[f]['selection'] = zip(selection.keys(),selection.values())
112 models.fields[f].update(fields[f])
113 add_field = False
114 if f in models.mfields and fields[f].get('type','') == 'one2many':
115@@ -352,7 +355,6 @@
116 models.fields[f] = fields[f]
117 models.fields[f]['name'] = f
118 to_add.append(f)
119-
120 self.mfields_load(to_add, models)
121 for fname in to_add:
122 for m in models.models:
123
124=== modified file 'bin/widget/model/record.py'
125--- bin/widget/model/record.py 2011-04-13 05:07:59 +0000
126+++ bin/widget/model/record.py 2011-04-19 08:45:00 +0000
127@@ -33,6 +33,7 @@
128 from gtk import glade
129 import tools
130 from field import O2MField
131+from field import SelectionField
132
133 class EvalEnvironment(object):
134 def __init__(self, parent):
135@@ -232,6 +233,9 @@
136 if self.mgroup.mfields[fieldname].attrs.get('on_change',False):
137 fields_with_on_change[fieldname] = value
138 else:
139+ if self.mgroup.mfields[fieldname].attrs.get('widget') == 'selection' and value:
140+ relation = self.mgroup.mfields[fieldname].attrs['relation']
141+ value = rpc.session.rpc_exec_auth('/object', 'execute', relation, 'name_search', '', [('id','=',value)], 'ilike')[0]
142 self.mgroup.mfields[fieldname].set_default(self, value)
143 for field, value in fields_with_on_change.items():
144 self.mgroup.mfields[field].set_default(self, value)
145
146=== modified file 'bin/widget/screen/screen.py'
147--- bin/widget/screen/screen.py 2011-04-13 09:12:58 +0000
148+++ bin/widget/screen/screen.py 2011-04-19 08:45:00 +0000
149@@ -592,13 +592,6 @@
150 if attrs['widget']=='one2many_list':
151 attrs['widget']='one2many'
152 attrs['type'] = attrs['widget']
153- if attrs.get('selection',[]):
154- attrs['selection'] = eval(attrs['selection'])
155- for att_key, att_val in attrs['selection'].items():
156- for sel in fields[str(attrs['name'])]['selection']:
157- if att_key == sel[0]:
158- sel[1] = att_val
159- attrs['selection'] = fields[str(attrs['name'])]['selection']
160 fields[unicode(attrs['name'])].update(attrs)
161 for node2 in node:
162 _parse_fields(node2, fields)
163@@ -617,7 +610,6 @@
164 self.models.screen = self
165 self.models.add_fields(fields, self.models, context=context)
166 self.fields = self.models.fields
167-
168 parser = widget_parse(parent=self.parent, window=self.window)
169 view = parser.parse(self, root_node, self.fields, toolbar=toolbar, submenu=submenu, help=help)
170 if view:
171
172=== modified file 'bin/widget/view/form_gtk/selection.py'
173--- bin/widget/view/form_gtk/selection.py 2010-07-16 05:41:32 +0000
174+++ bin/widget/view/form_gtk/selection.py 2011-04-19 08:45:00 +0000
175@@ -23,7 +23,7 @@
176 import interface
177 import gtk
178 import gobject
179-
180+import rpc
181 import gettext
182
183 class selection(interface.widget_interface):
184@@ -31,109 +31,83 @@
185 interface.widget_interface.__init__(self, window, parent, model, attrs)
186
187 self.widget = gtk.HBox(spacing=3)
188- self.entry = gtk.ComboBoxEntry()
189+ self.name = attrs['name']
190+ self.attrs = attrs
191+ self.entry = gtk.combo_box_entry_new_text()
192+ self.entry.connect('notify::popup-shown', self.popup_show)
193 self.child = self.entry.get_child()
194+ self.relation_model = self.attrs.get('relation', '')
195 self.child.set_property('activates_default', True)
196 self.child.connect('changed', self.sig_changed)
197 self.child.connect('populate-popup', self._menu_open)
198- self.child.connect('key_press_event', self.sig_key_press)
199- self.child.connect('activate', self.sig_activate)
200 self.child.connect_after('focus-out-event', self.sig_activate)
201- self.entry.set_size_request(int(attrs.get('size', -1)), -1)
202 self.widget.pack_start(self.entry, expand=True, fill=True)
203
204 # the dropdown button is not focusable by a tab
205 self.widget.set_focus_chain([self.child])
206- self.ok = True
207+ self.set_popdown(attrs.get('selection',[]))
208 self._selection={}
209-
210- self.set_popdown(attrs.get('selection', []))
211+ self.entry_text = ""
212+
213+
214+ def popup_show(self, combobox, popup_show):
215+ text = self.child.get_text()
216+# if self._view.modelfield.selection.get_key(text):
217+# text = ""
218+ if combobox.get_property('popup-shown') and self.attrs.get('widget','') == 'selection':
219+ domain = self._view.modelfield.domain_get(self._view.model)
220+ context = self._view.modelfield.context_get(self._view.model)
221+ selection = rpc.session.rpc_exec_auth('/object', 'execute', self.relation_model, 'name_search', text , domain , 'ilike', context , False)
222+ self.set_popdown(selection)
223
224 def set_popdown(self, selection):
225- self.model = gtk.ListStore(gobject.TYPE_STRING)
226+ self.model = self.entry.get_model()
227+ self.model.clear()
228 self._selection={}
229 lst = []
230- for (value, name) in selection:
231- name = str(name)
232+ if not selection:
233+ selection = [(False, '')]
234+ for (i,j) in selection:
235+ name = str(j)
236 lst.append(name)
237- self._selection[name] = value
238- i = self.model.append()
239- self.model.set(i, 0, name)
240- self.entry.set_model(self.model)
241- self.entry.set_text_column(0)
242- return lst
243+ self._selection[i]=name
244+ self.entry.append_text(name)
245
246 def _readonly_set(self, value):
247 interface.widget_interface._readonly_set(self, value)
248 self.entry.set_sensitive(not value)
249
250- def value_get(self):
251- res = self.child.get_text()
252- return self._selection.get(res, False)
253-
254- def sig_key_press(self, widget, event):
255- # allow showing available entries by hitting "ctrl+space"
256- completion=gtk.EntryCompletion()
257- if hasattr(completion, 'set_inline_selection'):
258- completion.set_inline_selection(True)
259- if (event.type == gtk.gdk.KEY_PRESS) \
260- and ((event.state & gtk.gdk.CONTROL_MASK) != 0) \
261- and (event.keyval == gtk.keysyms.space):
262- self.entry.popup()
263- elif not (event.keyval == gtk.keysyms.Up or event.keyval == gtk.keysyms.Down):
264- completion.set_match_func(self.match_func,widget)
265- completion.set_model(self.model)
266- widget.set_completion(completion)
267- completion.set_text_column(0)
268-
269- def match_func(self, completion, key, iter, widget):
270- model = completion.get_model()
271- return model[iter][0].lower().find(widget.get_text().lower()) >= 0 and True or False
272-
273 def sig_activate(self, *args):
274 text = self.child.get_text()
275- value = False
276- if text:
277- for txt, val in self._selection.items():
278- if not val:
279- continue
280- if txt[:len(text)].lower() == text.lower():
281- value = val
282- if len(txt) == len(text):
283- break
284+ value = self._view.modelfield.selection.get_key(text)
285+ if not value:
286+ self.entry_text = text
287 self._view.modelfield.set_client(self._view.model, value, force_change=True)
288 self.display(self._view.model, self._view.modelfield)
289
290-
291 def set_value(self, model, model_field):
292- model_field.set_client(model, self.value_get())
293-
294- def _menu_sig_default_set(self):
295- self.set_value(self._view.model, self._view.modelfield)
296- super(selection, self)._menu_sig_default_set()
297+ model_field.selection.update(self._selection)
298+ text = self.child.get_text()
299+ value = False
300+ if text:
301+ model_field.selection.get_key(text)
302+ value = model_field.selection.get_key(text)
303+ model_field.set_client(model, value)
304
305 def display(self, model, model_field):
306- self.ok = False
307 if not model_field:
308 self.child.set_text('')
309- self.ok = True
310- return False
311+ return
312+ model_field.selection.update(dict(self.attrs.get('selection',[])))
313 super(selection, self).display(model, model_field)
314- value = model_field.get(model)
315- if not value:
316- self.child.set_text('')
317- else:
318- found = False
319- for long_text, sel_value in self._selection.items():
320- if sel_value == value:
321- self.child.set_text(long_text)
322- found = True
323- break
324- self.ok = True
325+ key = model_field.get(model, False)
326+# model_field.selection.update(self._selection)
327+ text = model_field.selection.get_value(key)
328+ self.child.set_text(self.entry_text or text)
329+ self.entry_text = ""
330
331- def sig_changed(self, *args):
332- if self.ok:
333- self._focus_out()
334+ def sig_changed(self, combox):
335+ self._focus_out()
336
337 def _color_widget(self):
338 return self.child
339@@ -141,4 +115,3 @@
340 def grab_focus(self):
341 return self.entry.grab_focus()
342 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
343-
344
345=== modified file 'bin/widget/view/list.py'
346--- bin/widget/view/list.py 2011-04-12 08:48:06 +0000
347+++ bin/widget/view/list.py 2011-04-19 08:45:00 +0000
348@@ -860,7 +860,7 @@
349 if col in self.widget_tree.handlers:
350 if self.widget_tree.handlers[col]:
351 renderer.disconnect(self.widget_tree.handlers[col])
352- self.widget_tree.handlers[col] = renderer.connect_after('editing-started', send_keys, self.widget_tree)
353+ self.widget_tree.handlers[col] = renderer.connect_after('editing-started', send_keys, self.widget_tree, col.name)
354
355
356 def set_invisible_attr(self):
357
358=== modified file 'bin/widget/view/tree_gtk/editabletree.py'
359--- bin/widget/view/tree_gtk/editabletree.py 2010-12-23 09:52:21 +0000
360+++ bin/widget/view/tree_gtk/editabletree.py 2011-04-19 08:45:00 +0000
361@@ -149,7 +149,12 @@
362 def get_cursor(self):
363 res = super(EditableTreeView, self).get_cursor()
364 return res
365-
366+
367+ def get_current_model(self):
368+ path, column = self.get_cursor()
369+ store = self.get_model()
370+ return store.get_value(store.get_iter(path), 0)
371+
372 def set_value(self):
373 path, column = self.get_cursor()
374 store = self.get_model()
375@@ -175,7 +180,7 @@
376 def on_keypressed(self, entry, event, cell_value):
377 path, column = self.get_cursor()
378 store = self.get_model()
379- model = store.get_value(store.get_iter(path), 0)
380+ model = self.get_current_model()
381 if event.keyval in self.leaving_events:
382 shift_pressed = bool(gtk.gdk.SHIFT_MASK & event.state)
383 if isinstance(entry, gtk.Entry):
384
385=== modified file 'bin/widget/view/tree_gtk/parser.py'
386--- bin/widget/view/tree_gtk/parser.py 2011-03-20 11:26:23 +0000
387+++ bin/widget/view/tree_gtk/parser.py 2011-04-19 08:45:00 +0000
388@@ -33,6 +33,7 @@
389 from editabletree import EditableTreeView
390 from widget.view import interface
391 from widget.view.list import group_record
392+from widget.model.field import SelectionField, M2OField
393 import time
394 import date_renderer
395
396@@ -47,13 +48,16 @@
397 import gobject
398 import pango
399
400-def send_keys(renderer, entry, position, treeview):
401- if entry:
402+def send_keys(renderer, entry, position, treeview, col_name):
403+ if entry:
404 entry.connect('key_press_event', treeview.on_keypressed, renderer.get_property('text'))
405 entry.set_data('renderer', renderer)
406 entry.editing_done_id = entry.connect('editing_done', treeview.on_editing_done)
407 if isinstance(entry, gtk.ComboBoxEntry):
408 entry.connect('changed', treeview.on_editing_done)
409+ if isinstance(entry, gtk.ComboBoxEntry):
410+ popup = treeview.cells[col_name].popup
411+ entry.connect('notify::popup-shown', popup, treeview)
412
413 def sort_model(column, screen):
414 unsaved_model = [x for x in screen.models if x.id == None or x.modified]
415@@ -107,10 +111,8 @@
416 treeview.sequence = False
417 treeview.connect("motion-notify-event", treeview.set_tooltip)
418 treeview.connect('key-press-event', treeview.on_tree_key_press)
419-
420 for node in root_node:
421 node_attrs = tools.node_attributes(node)
422-
423 if node.tag == 'button':
424 cell = Cell('button')(node_attrs['string'], treeview, node_attrs)
425 cell.name = node_attrs['name']
426@@ -158,16 +160,17 @@
427 self.window)
428 treeview.cells[fname] = cell
429 renderer = cell.renderer
430-
431+ col = gtk.TreeViewColumn(None, renderer)
432+ col.name = fname
433 write_enable = editable and not node_attrs.get('readonly', False)
434 if isinstance(renderer, gtk.CellRendererToggle):
435 renderer.set_property('activatable', write_enable)
436 elif isinstance(renderer, (gtk.CellRendererText, gtk.CellRendererCombo, date_renderer.DecoratorRenderer)):
437 renderer.set_property('editable', write_enable)
438 if write_enable:
439- handler_id = renderer.connect_after('editing-started', send_keys, treeview)
440-
441- col = gtk.TreeViewColumn(None, renderer)
442+ handler_id = renderer.connect_after('editing-started', send_keys, treeview, col.name)
443+
444+
445 treeview.handlers[col] = handler_id
446 col_label = gtk.Label('')
447 if fields[fname].get('required', False):
448@@ -176,7 +179,7 @@
449 col_label.set_text(fields[fname]['string'])
450 col_label.show()
451 col.set_widget(col_label)
452- col.name = fname
453+
454 col._type = fields[fname]['type']
455 col.set_cell_data_func(renderer, cell.setter)
456 col.set_clickable(True)
457@@ -549,6 +552,13 @@
458 return rpc.name_get([found[0]], context)[0]
459 else:
460 return False, None
461+
462+ def get_textual_value(self, model):
463+ if isinstance(model[self.field_name], SelectionField):
464+ key = model[self.field_name].get_client(model)
465+ return model[self.field_name].selection.get_value(key)
466+ return model[self.field_name].get_client(model) or ''
467+
468
469
470 class O2M(Char):
471@@ -609,29 +619,46 @@
472 def __init__(self, *args):
473 super(Selection, self).__init__(*args)
474 self.renderer = gtk.CellRendererCombo()
475- selection_data = gtk.ListStore(object, str)
476- for x in self.attrs.get('selection', []):
477- selection_data.append(x)
478- self.renderer.set_property('model', selection_data)
479+ self.selection_data = gtk.ListStore(str, str)
480+ selection = self.attrs.get('selection', [])
481+ for x in selection:
482+ self.selection_data.append(x)
483+ if not selection:
484+ self.selection_data.append([False, ''])
485+ self.renderer.set_property('model', self.selection_data)
486 self.renderer.set_property('text-column', 1)
487+ self.relation = self.attrs.get('relation')
488
489 def get_textual_value(self, model):
490- selection = dict(self.attrs['selection'])
491- selection_value = selection.get(model[self.field_name].get(model), '')
492+ key = model[self.field_name].get(model)
493+ selection_value = model[self.field_name].selection.get_value(key)
494 if isinstance(model, group_record):
495 return selection_value + model[self.field_name].count
496 return selection_value
497+
498+ def popup(self, combobox, para, treeview):
499+ if combobox.get_property('popup-shown') and self.relation:
500+ entry = combobox.get_child()
501+ text = entry.get_property('text')
502+ rpc = RPCProxy(self.relation)
503+ model = treeview.get_current_model()
504+ domain = model[self.field_name].domain_get(model)
505+ context = model[self.field_name].context_get(model)
506+ key = model[self.field_name].selection.get_key(text)
507+ if key:
508+ text = ''
509+ selection = rpc.name_search(text, domain, 'ilike',context, False)
510+ if selection:
511+ self.selection_data.clear()
512+ model = treeview.get_current_model()
513+ model[self.field_name].selection.update(dict(selection))
514+ for x in selection:
515+ self.selection_data.append(x)
516
517 def value_from_text(self, model, text):
518- selection = self.attrs['selection']
519- text = tools.ustr(text)
520- res = False
521- for val, txt in selection:
522- if txt[:len(text)].lower() == text.lower():
523- if len(txt) == len(text):
524- return val
525- res = val
526- return res
527+ key = model[self.field_name].get(model)
528+ selection_value = model[self.field_name].selection.get_value(key)
529+ return model[self.field_name].selection.get_key(text)
530
531
532 class ProgressBar(object):
533
534=== modified file 'bin/widget_search/selection.py'
535--- bin/widget_search/selection.py 2011-04-04 11:19:53 +0000
536+++ bin/widget_search/selection.py 2011-04-19 08:45:00 +0000
537@@ -28,25 +28,37 @@
538 class selection(wid_int.wid_int):
539 def __init__(self, name, parent, attrs={}, model=None, screen=None):
540 wid_int.wid_int.__init__(self, name, parent, attrs, screen)
541-
542 self.widget = gtk.combo_box_entry_new_text()
543+ self.widget.connect('notify::popup-shown', self.popup_show)
544+ self.context = screen.context
545+ self.relation_model = self.attrs.get('relation', '')
546 self.widget.child.set_editable(True)
547 self.attrs = attrs
548 self._selection = {}
549 self.name = name
550- self.val_id = False
551- if 'selection' in attrs:
552- self.set_popdown(attrs.get('selection',[]))
553+ self.set_popdown(attrs.get('selection',[]))
554 if self.default_search:
555 if isinstance(self.default_search,list):
556 self.default_search = self.default_search[0]
557 if self.attrs['type'] == 'many2one':
558- self._value_set(int(self.default_search))
559+ sel = rpc.session.rpc_exec_auth('/object', 'execute', self.relation_model, 'name_search', '' , [('id','=',self.default_search)] , 'ilike', self.context, False)
560+ self.set_popdown(sel)
561+ self._value_set(int(self.default_search))
562 else:
563 self._value_set(str(self.default_search))
564 if self.widget.child.get_text() in self._selection.keys():
565 self.widget.set_active(self.indexes[self.widget.child.get_text()]-1)
566
567+ def popup_show(self, combobox, popup_show):
568+ search_text = self.widget.child.get_text()
569+# if self._selection.get(search_text, False):
570+# search_text =''
571+ if combobox.get_property('popup-shown') and self.attrs['type'] == 'many2one':
572+ selection = rpc.session.rpc_exec_auth('/object', 'execute', self.relation_model, 'name_search', search_text , [] , 'ilike', self.context, False)
573+ self.set_popdown(selection)
574+ if not selection:
575+ self.widget.child.set_text('')
576+
577 def set_popdown(self, selection):
578 self.model = self.widget.get_model()
579 self.model.clear()