Reviewers: ,
Please review this at http://codereview.tryton.org/590003/
Affected files:
M CHANGELOG
M tryton/common/domain_parser.py
M tryton/gui/window/view_form/view/screen_container.py
Index: CHANGELOG
===================================================================
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,5 @@
+* Allow multi-selection for Selection field in filter box
+
Version 2.6.0 - 2012-10-22
* Bug fixes (see mercurial logs for details)
* Allow to paste in editable list view
Index: tryton/common/domain_parser.py
===================================================================
--- a/tryton/common/domain_parser.py
+++ b/tryton/common/domain_parser.py
@@ -569,9 +569,15 @@
yield True
def complete_selection():
+ test_value = value
+ if isinstance(value, list):
+ test_value = value[-1]
for svalue, test in field['selection']:
- if test.lower().startswith(value.lower()):
- yield svalue
+ if test.lower().startswith(test_value.lower()):
+ if test_value == value:
+ yield svalue
+ else:
+ yield value[:-1] + [svalue]
def complete_datetime():
yield datetime.date.today()
@@ -594,6 +600,23 @@
return completes.get(field['type'], lambda: [])()
+def test_complete_selection():
+ field = {
+ 'type': 'selection',
+ 'selection': [
+ ('male', 'Male'),
+ ('female', 'Female'),
+ ],
+ }
+ for value, result in (
+ ('m', ['male']),
+ ('test', []),
+ ('', ['male', 'female']),
+ (['male', 'f'], [['male', 'female']]),
+ ):
+ assert list(complete_value(field, value)) == result
+
+
def parenthesize(tokens):
"Nest tokens according to parenthesis"
for token in tokens:
@@ -944,7 +967,10 @@
(field['name'], '<', rvalue),
])
continue
- value = convert_value(field, value)
+ if isinstance(value, list):
+ value = [convert_value(field, v) for v in value]
+ else:
+ value = convert_value(field, value)
yield field['name'], operator, value
@@ -1077,6 +1103,15 @@
'name': 'integer',
'type': 'integer',
},
+ 'selection': {
+ 'string': 'Selection',
+ 'name': 'selection',
+ 'type': 'selection',
+ 'selection': [
+ ('male', 'Male'),
+ ('female', 'Female'),
+ ],
+ },
})
assert rlist(dom.parse_clause([('John',)])) == [
('rec_name', 'ilike', '%John%')]
@@ -1090,6 +1125,10 @@
assert rlist(dom.parse_clause([('Name', '!', ['John', 'Jane'])])) == [
('name', 'not in', ['John', 'Jane']),
]
+ assert rlist(dom.parse_clause([('Selection', None,
['Male', 'Female'])])) \
+ == [
+ ('selection', 'in', ['male', 'female'])
+ ]
assert rlist(dom.parse_clause([('Integer', None, '3..5')])) == [[
('integer', '>=', 3),
('integer', '<', 5),
Index: tryton/gui/window/view_form/view/screen_container.py
===================================================================
--- a/tryton/gui/window/view_form/view/screen_container.py
+++ b/tryton/gui/window/view_form/view/screen_container.py
@@ -15,6 +15,35 @@
_ = gettext.gettext
+class Selection(gtk.ScrolledWindow):
+
+ def __init__(self, selections):
+ super(Selection, self).__init__()
+ self.treeview = gtk.TreeView()
+ model = gtk.ListStore(gobject.TYPE_STRING)
+ for selection in selections:
+ model.append((selection,))
+ self.treeview.set_model(model)
+
+ column = gtk.TreeViewColumn()
+ cell = gtk.CellRendererText()
+ column.pack_start(cell)
+ column.add_attribute(cell, 'text', 0)
+ self.treeview.append_column(column)
+ self.treeview.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
+ self.treeview.set_headers_visible(False)
+ self.add(self.treeview)
+ self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+
+ def get_value(self):
+ values = []
+ model, paths = self.treeview.get_selection().get_selected_rows()
+ for path in paths:
+ iter_ = model.get_iter(path)
+ values.append(model.get_value(iter_, 0))
+ return ';'.join(quote(v) for v in values)
+
+
class ScreenContainer(object):
def __init__(self):
@@ -213,11 +242,13 @@
text = ''
for label, entry in self.search_table.fields:
if isinstance(entry, gtk.ComboBox):
- value = entry.get_active_text()
+ value = quote(entry.get_active_text())
+ elif isinstance(entry, Selection):
+ value = entry.get_value()
else:
- value = entry.get_text()
+ value = quote(entry.get_text())
if value:
- text += label + ' ' + quote(value) + ' '
+ text += label + ' ' + value + ' '
self.set_text(text)
self.do_search()
@@ -255,18 +286,18 @@
label = gtk.Label(field['string'])
label.set_alignment(0.0, 0.5)
self.search_table.attach(label, 0, 1, i, i + 1)
- if field['type'] in ('boolean', 'selection'):
+ if field['type'] == 'boolean':
if hasattr(gtk, 'ComboBoxText'):
entry = gtk.ComboBoxText()
else:
entry = gtk.combo_box_new_text()
entry.append_text('')
- if field['type'] == 'boolean':
- selections = (_('True'), _('False'))
- else:
- selections = tuple(x[1] for x in
field['selection'])
+ selections = (_('True'), _('False'))
for selection in selections:
entry.append_text(selection)
+ elif field['type'] == 'selection':
+ selections = tuple(x[1] for x in field['selection'])
+ entry = Selection(selections)
elif field['type'] in ('date', 'datetime', 'time'):
if field['type'] == 'date':
format_ = date_format()
--
[email protected] mailing list