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

Proposed by Ravi Gadhia (OpenERP)
Status: Superseded
Proposed branch: lp:~openerp-dev/openobject-client/trunk-m2o_with_selection-rga
Merge into: lp:openobject-client
Diff against target: 531 lines (+159/-110)
8 files modified
bin/widget/model/field.py (+33/-6)
bin/widget/model/record.py (+4/-0)
bin/widget/screen/screen.py (+2/-0)
bin/widget/view/form_gtk/selection.py (+47/-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 (+14/-4)
To merge this branch: bzr merge lp:~openerp-dev/openobject-client/trunk-m2o_with_selection-rga
Reviewer Review Type Date Requested Status
Naresh(OpenERP) Needs Resubmitting
Review via email: mp+53391@code.launchpad.net

This proposal has been superseded by a proposal from 2011-04-19.

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 :

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
1838. By Ravi Gadhia (OpenERP)

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

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)

1840. By Ravi Gadhia (OpenERP)

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

1841. By Ravi Gadhia (OpenERP)

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

1842. By Ravi Gadhia (OpenERP)

Merge with trunk client

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
=== modified file 'bin/widget/model/field.py'
--- bin/widget/model/field.py 2011-02-14 11:00:02 +0000
+++ bin/widget/model/field.py 2011-03-15 09:59:07 +0000
@@ -45,12 +45,31 @@
45 klass = TYPES.get(type, CharField)45 klass = TYPES.get(type, CharField)
46 return klass46 return klass
4747
48class M2O_SelectionField(dict):
49 def __init__(self ,*args, **kwargs):
50 self.swap = {}
51
52 def __setitem__(self, key, value):
53 self.swap[value] = key
54 super(M2O_SelectionField, self).__setitem__(key, value)
55
56 def update(self, *args, **kwargs):
57 for key, val in args[0].items():
58 self.swap[val] = key
59 super(M2O_SelectionField, self).update(args[0])
60
61 def get_value(self, key):
62 return self.get(key, '')
63
64 def get_key(self,value):
65 return self.swap.get(value, False)
4866
49class CharField(object):67class CharField(object):
50 def __init__(self, parent, attrs):68 def __init__(self, parent, attrs):
51 self.parent = parent69 self.parent = parent
52 self.attrs = attrs70 self.attrs = attrs
53 self.name = attrs['name']71 self.name = attrs['name']
72 self.selection = M2O_SelectionField()
54 self.internal = False73 self.internal = False
55 self.default_attrs = {}74 self.default_attrs = {}
5675
@@ -103,12 +122,12 @@
103 return True122 return True
104123
105 def get(self, model, check_load=True, readonly=True, modified=False):124 def get(self, model, check_load=True, readonly=True, modified=False):
106 return model.value.get(self.name, False) or False125 return model.value.get(self.name, False)
107126
108 def set_client(self, model, value, test_state=True, force_change=False):127 def set_client(self, model, value, test_state=True, force_change=False):
109 internal = model.value.get(self.name, False)128 internal = model.value.get(self.name, False)
110 self.set(model, value, test_state)129 self.set(model, value, test_state)
111 if (internal or False) != (model.value.get(self.name,False) or False):130 if (internal or False) != (model.value.get(self.name, False) or False):
112 model.modified = True131 model.modified = True
113 model.modified_fields.setdefault(self.name)132 model.modified_fields.setdefault(self.name)
114 self.sig_changed(model)133 self.sig_changed(model)
@@ -135,7 +154,7 @@
135 try:154 try:
136 attrs_changes = eval(self.attrs.get('attrs',"{}"))155 attrs_changes = eval(self.attrs.get('attrs',"{}"))
137 except:156 except:
138 attrs_changes = eval(self.attrs.get('attrs',"{}"),model.value)157 attrs_changes = eval(self.attrs.get('attrs',"{}"), model.value)
139 for k,v in attrs_changes.items():158 for k,v in attrs_changes.items():
140 for i in range(0,len(v)):159 for i in range(0,len(v)):
141 if v[i][2]:160 if v[i][2]:
@@ -236,14 +255,21 @@
236255
237256
238class SelectionField(CharField):257class SelectionField(CharField):
258
259 def get(self, model, check_load=True, readonly=True, modified=False):
260 return model.value.get(self.name, False)
261
239 def set(self, model, value, test_state=True, modified=False):262 def set(self, model, value, test_state=True, modified=False):
263 self.selection.update(dict(self.attrs.get('selection',[])))
264 if isinstance(value,(list,tuple)) and len(value):
265 self.selection[value[0]] = value[1]
266
240 value = isinstance(value,(list,tuple)) and len(value) and value[0] or value267 value = isinstance(value,(list,tuple)) and len(value) and value[0] or value
241268
242 if not self.get_state_attrs(model).get('required', False) and value is None:269 if not self.get_state_attrs(model).get('required', False) and value is None:
243 super(SelectionField, self).set(model, value, test_state, modified)270 super(SelectionField, self).set(model, value, test_state, modified)
244271
245 if value in [sel[0] for sel in self.attrs['selection']]:272 super(SelectionField, self).set(model, value, test_state, modified)
246 super(SelectionField, self).set(model, value, test_state, modified)
247273
248class FloatField(CharField):274class FloatField(CharField):
249 def validate(self, model):275 def validate(self, model):
@@ -297,6 +323,7 @@
297 def get_client(self, model):323 def get_client(self, model):
298 #model._check_load()324 #model._check_load()
299 if model.value[self.name]:325 if model.value[self.name]:
326 self.selection.update(dict([model.value[self.name]]))
300 return model.value[self.name][1]327 return model.value[self.name][1]
301 return False328 return False
302329
303330
=== modified file 'bin/widget/model/record.py'
--- bin/widget/model/record.py 2011-02-04 06:19:22 +0000
+++ bin/widget/model/record.py 2011-03-15 09:59:07 +0000
@@ -33,6 +33,7 @@
33from gtk import glade33from gtk import glade
34import tools34import tools
35from field import O2MField35from field import O2MField
36from field import SelectionField
3637
37class EvalEnvironment(object):38class EvalEnvironment(object):
38 def __init__(self, parent):39 def __init__(self, parent):
@@ -230,6 +231,9 @@
230 if self.mgroup.mfields[fieldname].attrs.get('on_change',False):231 if self.mgroup.mfields[fieldname].attrs.get('on_change',False):
231 fields_with_on_change[fieldname] = value232 fields_with_on_change[fieldname] = value
232 else:233 else:
234 if self.mgroup.mfields[fieldname].attrs.get('widget') == 'selection' and value:
235 relation = self.mgroup.mfields[fieldname].attrs['relation']
236 value = rpc.session.rpc_exec_auth('/object', 'execute', relation, 'name_search', '', [('id','=',value)], 'ilike')[0]
233 self.mgroup.mfields[fieldname].set_default(self, value)237 self.mgroup.mfields[fieldname].set_default(self, value)
234 for field, value in fields_with_on_change.items():238 for field, value in fields_with_on_change.items():
235 self.mgroup.mfields[field].set_default(self, value)239 self.mgroup.mfields[field].set_default(self, value)
236240
=== modified file 'bin/widget/screen/screen.py'
--- bin/widget/screen/screen.py 2011-01-27 12:43:03 +0000
+++ bin/widget/screen/screen.py 2011-03-15 09:59:07 +0000
@@ -593,6 +593,8 @@
593 if attrs.get('widget', False):593 if attrs.get('widget', False):
594 if attrs['widget']=='one2many_list':594 if attrs['widget']=='one2many_list':
595 attrs['widget']='one2many'595 attrs['widget']='one2many'
596# attrs['py_field_type'] = attrs['type']
597 attrs['py_type'] = fields[str(attrs['name'])]['type']
596 attrs['type'] = attrs['widget']598 attrs['type'] = attrs['widget']
597 if attrs.get('selection',[]):599 if attrs.get('selection',[]):
598 attrs['selection'] = eval(attrs['selection'])600 attrs['selection'] = eval(attrs['selection'])
599601
=== modified file 'bin/widget/view/form_gtk/selection.py'
--- bin/widget/view/form_gtk/selection.py 2010-07-16 05:41:32 +0000
+++ bin/widget/view/form_gtk/selection.py 2011-03-15 09:59:07 +0000
@@ -23,7 +23,7 @@
23import interface23import interface
24import gtk24import gtk
25import gobject25import gobject
2626import rpc
27import gettext27import gettext
2828
29class selection(interface.widget_interface):29class selection(interface.widget_interface):
@@ -31,109 +31,84 @@
31 interface.widget_interface.__init__(self, window, parent, model, attrs)31 interface.widget_interface.__init__(self, window, parent, model, attrs)
3232
33 self.widget = gtk.HBox(spacing=3)33 self.widget = gtk.HBox(spacing=3)
34 self.entry = gtk.ComboBoxEntry()34 self.name = attrs['name']
35 self.attrs = attrs
36 self.entry = gtk.combo_box_entry_new_text()
37 self.entry.connect('notify::popup-shown', self.popup_show)
35 self.child = self.entry.get_child()38 self.child = self.entry.get_child()
39 self.relation_model = self.attrs.get('relation', '')
36 self.child.set_property('activates_default', True)40 self.child.set_property('activates_default', True)
37 self.child.connect('changed', self.sig_changed)41 self.child.connect('changed', self.sig_changed)
38 self.child.connect('populate-popup', self._menu_open)42 self.child.connect('populate-popup', self._menu_open)
39 self.child.connect('key_press_event', self.sig_key_press)
40 self.child.connect('activate', self.sig_activate)
41 self.child.connect_after('focus-out-event', self.sig_activate)43 self.child.connect_after('focus-out-event', self.sig_activate)
42 self.entry.set_size_request(int(attrs.get('size', -1)), -1)
43 self.widget.pack_start(self.entry, expand=True, fill=True)44 self.widget.pack_start(self.entry, expand=True, fill=True)
4445
45 # the dropdown button is not focusable by a tab46 # the dropdown button is not focusable by a tab
46 self.widget.set_focus_chain([self.child])47 self.widget.set_focus_chain([self.child])
47 self.ok = True48 self.set_popdown(attrs.get('selection',[]))
48 self._selection={}49 self._selection={}
4950 self.entry_text = ""
50 self.set_popdown(attrs.get('selection', []))51
52
53 def popup_show(self, combobox, popup_show):
54 text = self.child.get_text()
55 if self._view.modelfield.selection.get_key(text):
56 text = ""
57# self.child.set_text(self.last_txt)
58 if combobox.get_property('popup-shown') and self.attrs.get('widget','') == 'selection':
59 domain = self._view.modelfield.domain_get(self._view.model)
60 context = self._view.modelfield.context_get(self._view.model)
61 selection = rpc.session.rpc_exec_auth('/object', 'execute', self.relation_model, 'name_search', text , domain , 'ilike', context , False)
62 self.set_popdown(selection)
5163
52 def set_popdown(self, selection):64 def set_popdown(self, selection):
53 self.model = gtk.ListStore(gobject.TYPE_STRING)65 self.model = self.entry.get_model()
66 self.model.clear()
54 self._selection={}67 self._selection={}
55 lst = []68 lst = []
56 for (value, name) in selection:69 if not selection:
57 name = str(name)70 selection = [(False, '')]
71 for (i,j) in selection:
72 name = str(j)
58 lst.append(name)73 lst.append(name)
59 self._selection[name] = value74 self._selection[i]=name
60 i = self.model.append()75 self.entry.append_text(name)
61 self.model.set(i, 0, name)
62 self.entry.set_model(self.model)
63 self.entry.set_text_column(0)
64 return lst
6576
66 def _readonly_set(self, value):77 def _readonly_set(self, value):
67 interface.widget_interface._readonly_set(self, value)78 interface.widget_interface._readonly_set(self, value)
68 self.entry.set_sensitive(not value)79 self.entry.set_sensitive(not value)
6980
70 def value_get(self):
71 res = self.child.get_text()
72 return self._selection.get(res, False)
73
74 def sig_key_press(self, widget, event):
75 # allow showing available entries by hitting "ctrl+space"
76 completion=gtk.EntryCompletion()
77 if hasattr(completion, 'set_inline_selection'):
78 completion.set_inline_selection(True)
79 if (event.type == gtk.gdk.KEY_PRESS) \
80 and ((event.state & gtk.gdk.CONTROL_MASK) != 0) \
81 and (event.keyval == gtk.keysyms.space):
82 self.entry.popup()
83 elif not (event.keyval == gtk.keysyms.Up or event.keyval == gtk.keysyms.Down):
84 completion.set_match_func(self.match_func,widget)
85 completion.set_model(self.model)
86 widget.set_completion(completion)
87 completion.set_text_column(0)
88
89 def match_func(self, completion, key, iter, widget):
90 model = completion.get_model()
91 return model[iter][0].lower().find(widget.get_text().lower()) >= 0 and True or False
92
93 def sig_activate(self, *args):81 def sig_activate(self, *args):
94 text = self.child.get_text()82 text = self.child.get_text()
95 value = False83 value = self._view.modelfield.selection.get_key(text)
96 if text:84 if not value:
97 for txt, val in self._selection.items():85 self.entry_text = text
98 if not val:
99 continue
100 if txt[:len(text)].lower() == text.lower():
101 value = val
102 if len(txt) == len(text):
103 break
104 self._view.modelfield.set_client(self._view.model, value, force_change=True)86 self._view.modelfield.set_client(self._view.model, value, force_change=True)
105 self.display(self._view.model, self._view.modelfield)87 self.display(self._view.model, self._view.modelfield)
10688
107
108 def set_value(self, model, model_field):89 def set_value(self, model, model_field):
109 model_field.set_client(model, self.value_get())90 model_field.selection.update(self._selection)
11091 text = self.child.get_text()
111 def _menu_sig_default_set(self):92 value = False
112 self.set_value(self._view.model, self._view.modelfield)93 if text:
113 super(selection, self)._menu_sig_default_set()94 model_field.selection.get_key(text)
95 value = model_field.selection.get_key(text)
96 model_field.set_client(model, value)
11497
115 def display(self, model, model_field):98 def display(self, model, model_field):
116 self.ok = False
117 if not model_field:99 if not model_field:
118 self.child.set_text('')100 self.child.set_text('')
119 self.ok = True101 return
120 return False102 model_field.selection.update(dict(self.attrs.get('selection',[])))
121 super(selection, self).display(model, model_field)103 super(selection, self).display(model, model_field)
122 value = model_field.get(model)104 key = model_field.get(model, False)
123 if not value:105# model_field.selection.update(self._selection)
124 self.child.set_text('')106 text = model_field.selection.get_value(key)
125 else:107 self.child.set_text(self.entry_text or text)
126 found = False108 self.entry_text = ""
127 for long_text, sel_value in self._selection.items():
128 if sel_value == value:
129 self.child.set_text(long_text)
130 found = True
131 break
132 self.ok = True
133109
134 def sig_changed(self, *args):110 def sig_changed(self, combox):
135 if self.ok:111 self._focus_out()
136 self._focus_out()
137112
138 def _color_widget(self):113 def _color_widget(self):
139 return self.child114 return self.child
@@ -141,4 +116,3 @@
141 def grab_focus(self):116 def grab_focus(self):
142 return self.entry.grab_focus()117 return self.entry.grab_focus()
143# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:118# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
144
145119
=== modified file 'bin/widget/view/list.py'
--- bin/widget/view/list.py 2011-03-04 12:04:50 +0000
+++ bin/widget/view/list.py 2011-03-15 09:59:07 +0000
@@ -848,7 +848,7 @@
848 if col in self.widget_tree.handlers:848 if col in self.widget_tree.handlers:
849 if self.widget_tree.handlers[col]:849 if self.widget_tree.handlers[col]:
850 renderer.disconnect(self.widget_tree.handlers[col])850 renderer.disconnect(self.widget_tree.handlers[col])
851 self.widget_tree.handlers[col] = renderer.connect_after('editing-started', send_keys, self.widget_tree)851 self.widget_tree.handlers[col] = renderer.connect_after('editing-started', send_keys, self.widget_tree, col.name)
852852
853853
854 def set_invisible_attr(self):854 def set_invisible_attr(self):
855855
=== modified file 'bin/widget/view/tree_gtk/editabletree.py'
--- bin/widget/view/tree_gtk/editabletree.py 2010-12-23 09:52:21 +0000
+++ bin/widget/view/tree_gtk/editabletree.py 2011-03-15 09:59:07 +0000
@@ -149,7 +149,12 @@
149 def get_cursor(self):149 def get_cursor(self):
150 res = super(EditableTreeView, self).get_cursor()150 res = super(EditableTreeView, self).get_cursor()
151 return res151 return res
152152
153 def get_current_model(self):
154 path, column = self.get_cursor()
155 store = self.get_model()
156 return store.get_value(store.get_iter(path), 0)
157
153 def set_value(self):158 def set_value(self):
154 path, column = self.get_cursor()159 path, column = self.get_cursor()
155 store = self.get_model()160 store = self.get_model()
@@ -175,7 +180,7 @@
175 def on_keypressed(self, entry, event, cell_value):180 def on_keypressed(self, entry, event, cell_value):
176 path, column = self.get_cursor()181 path, column = self.get_cursor()
177 store = self.get_model()182 store = self.get_model()
178 model = store.get_value(store.get_iter(path), 0)183 model = self.get_current_model()
179 if event.keyval in self.leaving_events:184 if event.keyval in self.leaving_events:
180 shift_pressed = bool(gtk.gdk.SHIFT_MASK & event.state)185 shift_pressed = bool(gtk.gdk.SHIFT_MASK & event.state)
181 if isinstance(entry, gtk.Entry):186 if isinstance(entry, gtk.Entry):
182187
=== modified file 'bin/widget/view/tree_gtk/parser.py'
--- bin/widget/view/tree_gtk/parser.py 2011-03-04 12:04:50 +0000
+++ bin/widget/view/tree_gtk/parser.py 2011-03-15 09:59:07 +0000
@@ -33,6 +33,7 @@
33from editabletree import EditableTreeView33from editabletree import EditableTreeView
34from widget.view import interface34from widget.view import interface
35from widget.view.list import group_record35from widget.view.list import group_record
36from widget.model.field import SelectionField, M2OField
36import time37import time
37import date_renderer38import date_renderer
3839
@@ -47,13 +48,16 @@
47import gobject48import gobject
48import pango49import pango
4950
50def send_keys(renderer, entry, position, treeview):51def send_keys(renderer, entry, position, treeview, col_name):
51 if entry:52 if entry:
52 entry.connect('key_press_event', treeview.on_keypressed, renderer.get_property('text'))53 entry.connect('key_press_event', treeview.on_keypressed, renderer.get_property('text'))
53 entry.set_data('renderer', renderer)54 entry.set_data('renderer', renderer)
54 entry.editing_done_id = entry.connect('editing_done', treeview.on_editing_done)55 entry.editing_done_id = entry.connect('editing_done', treeview.on_editing_done)
55 if isinstance(entry, gtk.ComboBoxEntry):56 if isinstance(entry, gtk.ComboBoxEntry):
56 entry.connect('changed', treeview.on_editing_done)57 entry.connect('changed', treeview.on_editing_done)
58 if isinstance(entry, gtk.ComboBoxEntry):
59 popup = treeview.cells[col_name].popup
60 entry.connect('notify::popup-shown', popup, treeview)
5761
58def sort_model(column, screen):62def sort_model(column, screen):
59 unsaved_model = [x for x in screen.models if x.id == None or x.modified]63 unsaved_model = [x for x in screen.models if x.id == None or x.modified]
@@ -107,10 +111,8 @@
107 treeview.sequence = False111 treeview.sequence = False
108 treeview.connect("motion-notify-event", treeview.set_tooltip)112 treeview.connect("motion-notify-event", treeview.set_tooltip)
109 treeview.connect('key-press-event', treeview.on_tree_key_press)113 treeview.connect('key-press-event', treeview.on_tree_key_press)
110
111 for node in root_node:114 for node in root_node:
112 node_attrs = tools.node_attributes(node)115 node_attrs = tools.node_attributes(node)
113
114 if node.tag == 'button':116 if node.tag == 'button':
115 cell = Cell('button')(node_attrs['string'], treeview, node_attrs)117 cell = Cell('button')(node_attrs['string'], treeview, node_attrs)
116 cell.name = node_attrs['name']118 cell.name = node_attrs['name']
@@ -158,16 +160,17 @@
158 self.window)160 self.window)
159 treeview.cells[fname] = cell161 treeview.cells[fname] = cell
160 renderer = cell.renderer162 renderer = cell.renderer
161163 col = gtk.TreeViewColumn(None, renderer)
164 col.name = fname
162 write_enable = editable and not node_attrs.get('readonly', False)165 write_enable = editable and not node_attrs.get('readonly', False)
163 if isinstance(renderer, gtk.CellRendererToggle):166 if isinstance(renderer, gtk.CellRendererToggle):
164 renderer.set_property('activatable', write_enable)167 renderer.set_property('activatable', write_enable)
165 elif isinstance(renderer, (gtk.CellRendererText, gtk.CellRendererCombo, date_renderer.DecoratorRenderer)):168 elif isinstance(renderer, (gtk.CellRendererText, gtk.CellRendererCombo, date_renderer.DecoratorRenderer)):
166 renderer.set_property('editable', write_enable)169 renderer.set_property('editable', write_enable)
167 if write_enable:170 if write_enable:
168 handler_id = renderer.connect_after('editing-started', send_keys, treeview)171 handler_id = renderer.connect_after('editing-started', send_keys, treeview, col.name)
169172
170 col = gtk.TreeViewColumn(None, renderer)173
171 treeview.handlers[col] = handler_id174 treeview.handlers[col] = handler_id
172 col_label = gtk.Label('')175 col_label = gtk.Label('')
173 if fields[fname].get('required', False):176 if fields[fname].get('required', False):
@@ -176,7 +179,7 @@
176 col_label.set_text(fields[fname]['string'])179 col_label.set_text(fields[fname]['string'])
177 col_label.show()180 col_label.show()
178 col.set_widget(col_label)181 col.set_widget(col_label)
179 col.name = fname182
180 col._type = fields[fname]['type']183 col._type = fields[fname]['type']
181 col.set_cell_data_func(renderer, cell.setter)184 col.set_cell_data_func(renderer, cell.setter)
182 col.set_clickable(True)185 col.set_clickable(True)
@@ -549,6 +552,13 @@
549 return rpc.name_get([found[0]], context)[0]552 return rpc.name_get([found[0]], context)[0]
550 else:553 else:
551 return False, None554 return False, None
555
556 def get_textual_value(self, model):
557 if isinstance(model[self.field_name], SelectionField):
558 key = model[self.field_name].get_client(model)
559 return model[self.field_name].selection.get_value(key)
560 return model[self.field_name].get_client(model) or ''
561
552562
553563
554class O2M(Char):564class O2M(Char):
@@ -609,29 +619,46 @@
609 def __init__(self, *args):619 def __init__(self, *args):
610 super(Selection, self).__init__(*args)620 super(Selection, self).__init__(*args)
611 self.renderer = gtk.CellRendererCombo()621 self.renderer = gtk.CellRendererCombo()
612 selection_data = gtk.ListStore(str, str)622 self.selection_data = gtk.ListStore(str, str)
613 for x in self.attrs.get('selection', []):623 selection = self.attrs.get('selection', [])
614 selection_data.append(x)624 for x in selection:
615 self.renderer.set_property('model', selection_data)625 self.selection_data.append(x)
626 if not selection:
627 self.selection_data.append([False, ''])
628 self.renderer.set_property('model', self.selection_data)
616 self.renderer.set_property('text-column', 1)629 self.renderer.set_property('text-column', 1)
630 self.relation = self.attrs.get('relation')
617631
618 def get_textual_value(self, model):632 def get_textual_value(self, model):
619 selection = dict(self.attrs['selection'])633 key = model[self.field_name].get(model)
620 selection_value = selection.get(model[self.field_name].get(model), '')634 selection_value = model[self.field_name].selection.get_value(key)
621 if isinstance(model, group_record):635 if isinstance(model, group_record):
622 return selection_value + model[self.field_name].count636 return selection_value + model[self.field_name].count
623 return selection_value637 return selection_value
638
639 def popup(self, combobox, para, treeview):
640 if combobox.get_property('popup-shown') and self.relation:
641 entry = combobox.get_child()
642 text = entry.get_property('text')
643 rpc = RPCProxy(self.relation)
644 model = treeview.get_current_model()
645 domain = model[self.field_name].domain_get(model)
646 context = model[self.field_name].context_get(model)
647 key = model[self.field_name].selection.get_key(text)
648 if key:
649 text = ''
650 selection = rpc.name_search(text, domain, 'ilike',context, False)
651 if selection:
652 self.selection_data.clear()
653 model = treeview.get_current_model()
654 model[self.field_name].selection.update(dict(selection))
655 for x in selection:
656 self.selection_data.append(x)
624657
625 def value_from_text(self, model, text):658 def value_from_text(self, model, text):
626 selection = self.attrs['selection']659 key = model[self.field_name].get(model)
627 text = tools.ustr(text)660 selection_value = model[self.field_name].selection.get_value(key)
628 res = False661 return model[self.field_name].selection.get_key(text)
629 for val, txt in selection:
630 if txt[:len(text)].lower() == text.lower():
631 if len(txt) == len(text):
632 return val
633 res = val
634 return res
635662
636663
637class ProgressBar(object):664class ProgressBar(object):
638665
=== modified file 'bin/widget_search/selection.py'
--- bin/widget_search/selection.py 2011-01-17 19:11:21 +0000
+++ bin/widget_search/selection.py 2011-03-15 09:59:07 +0000
@@ -28,15 +28,15 @@
28class selection(wid_int.wid_int):28class selection(wid_int.wid_int):
29 def __init__(self, name, parent, attrs={}, model=None, screen=None):29 def __init__(self, name, parent, attrs={}, model=None, screen=None):
30 wid_int.wid_int.__init__(self, name, parent, attrs, screen)30 wid_int.wid_int.__init__(self, name, parent, attrs, screen)
31
32 self.widget = gtk.combo_box_entry_new_text()31 self.widget = gtk.combo_box_entry_new_text()
32 self.widget.connect('notify::popup-shown', self.popup_show)
33 self.context = screen.context
34 self.relation_model = self.attrs.get('relation', '')
33 self.widget.child.set_editable(True)35 self.widget.child.set_editable(True)
34 self.attrs = attrs36 self.attrs = attrs
35 self._selection = {}37 self._selection = {}
36 self.name = name38 self.name = name
37 self.val_id = False39 self.set_popdown(attrs.get('selection',[]))
38 if 'selection' in attrs:
39 self.set_popdown(attrs.get('selection',[]))
40 if self.default_search:40 if self.default_search:
41 if self.attrs['type'] == 'many2one':41 if self.attrs['type'] == 'many2one':
42 self._value_set(int(self.default_search))42 self._value_set(int(self.default_search))
@@ -45,6 +45,16 @@
45 if self.widget.child.get_text() in self._selection.keys():45 if self.widget.child.get_text() in self._selection.keys():
46 self.widget.set_active(self.indexes[self.widget.child.get_text()]-1)46 self.widget.set_active(self.indexes[self.widget.child.get_text()]-1)
4747
48 def popup_show(self, combobox, popup_show):
49 search_text = self.widget.child.get_text()
50 if self._selection.get(search_text, False):
51 search_text =''
52 if combobox.get_property('popup-shown') and self.attrs['type'] == 'many2one':
53 selection = rpc.session.rpc_exec_auth('/object', 'execute', self.relation_model, 'name_search', search_text , [] , 'ilike', self.context, False)
54 self.set_popdown(selection)
55 if not selection:
56 self.widget.child.set_text('')
57
48 def set_popdown(self, selection):58 def set_popdown(self, selection):
49 self.model = self.widget.get_model()59 self.model = self.widget.get_model()
50 self.model.clear()60 self.model.clear()