Add operator on search widgets

This commit is contained in:
Cédric Krier committed 2008-09-26 11:44:19 +02:00
1 parent 9015bb48b3
commit 491ee2313e
8 files changed
+308 -94

No files matched your search

@@ -9,6 +9,7 @@ from tryton.common import DT_FORMAT
from tryton.common import date_widget
from tryton.translate import date_format
import mx.DateTime
import gobject
_ = gettext.gettext
@@ -23,7 +24,23 @@ class Calendar(Interface):
self.format = date_format()
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.combo = gtk.ComboBox(self.liststore)
cell = gtk.CellRendererText()
self.combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 1)
for oper in (['=', _('at')],
['between', _('between')],
['not between', _('not between')],
['!=', _('not at')],
):
self.liststore.append(oper)
self.combo.set_active(0)
self.widget.pack_start(self.combo, False, False)
self.combo.connect('changed', self._changed)
self.widget1 = date_widget.ComplexEntry(self.format, spacing=3)
self.widget1.show()
self.entry1 = self.widget1.widget
self.entry1.set_property('width-chars', 10)
self.entry1.set_property('activates_default', True)
@@ -41,7 +58,8 @@ class Calendar(Interface):
self.eb1.add(img)
self.widget.pack_start(self.eb1, expand=False, fill=False)
self.widget.pack_start(gtk.Label('-'), expand=False, fill=False)
self.separator = gtk.Label('-')
self.widget.pack_start(self.separator, expand=False, fill=False)
self.widget2 = date_widget.ComplexEntry(self.format, spacing=3)
self.entry2 = self.widget2.widget
@@ -61,8 +79,22 @@ class Calendar(Interface):
self.eb2.add(img)
self.widget.pack_start(self.eb2, expand=False, fill=False)
self.widget.show_all()
self._changed(self.combo)
tooltips.enable()
def _changed(self, widget):
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if oper in ('=', '!='):
self.entry2.hide()
self.separator.hide()
self.eb2.hide()
else:
self.entry2.show()
self.separator.show()
self.eb2.show()
def _date_get(self, value):
try:
date = mx.DateTime.strptime(value, self.format)
@@ -71,14 +103,24 @@ class Calendar(Interface):
return date.strftime(DT_FORMAT)
def _value_get(self):
res = []
val = self._date_get(self.entry1.get_text())
if val:
res.append((self.name, '>=', val))
val = self._date_get(self.entry2.get_text())
if val:
res.append((self.name, '<=', val))
return res
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if oper in ('=', '!='):
return [(self.name, oper, self._date_get(self.entry1.get_text()))]
else:
res = []
if oper == 'between':
oper1 = '>='
oper2 = '<='
else:
oper1 = '<='
oper2 = '>='
val = self._date_get(self.entry1.get_text())
if val:
res.append((self.name, oper1, val))
val = self._date_get(self.entry2.get_text())
if val:
res.append((self.name, oper2, val))
return res
def _value_set(self, value):
def conv(value):
@@ -90,16 +132,18 @@ class Calendar(Interface):
except:
return ''
val = conv(value[0])
if val:
self.entry1.set_text()
else:
self.entry1.clear()
val = conv(value[1])
if val:
self.entry2.set_text()
else:
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
self.entry1.set_text(conv(value[1]))
if len(value) == 2:
self.entry2.clear()
else:
self.entry2.set_text(conv(value[2]))
value = property(_value_get, _value_set)
@@ -134,7 +178,7 @@ class Calendar(Interface):
win.destroy()
def clear(self):
self.value = ('', '')
self.value = ('=', '')
def sig_activate(self, fct):
self.entry1.connect_after('activate', fct)
@@ -2,6 +2,7 @@
import gtk
import gettext
from interface import Interface
import gobject
_ = gettext.gettext
@@ -13,29 +14,57 @@ class Char(Interface):
attrs = {}
super(Char, self).__init__(name, parent, attrs)
self.widget = gtk.Entry()
self.widget.set_max_length(int(attrs.get('size', 0)))
self.widget.set_width_chars(5)
self.widget.set_property('activates_default', True)
self.widget = gtk.HBox()
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.combo = gtk.ComboBox(self.liststore)
cell = gtk.CellRendererText()
self.combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 1)
for oper in (['ilike', _('contains')],
['not ilike', _('not contains')],
['=', _('equal')],
['!=', _('different')],
):
self.liststore.append(oper)
self.combo.set_active(0)
self.widget.pack_start(self.combo, False, False)
self.entry = gtk.Entry()
self.entry.set_max_length(int(attrs.get('size', 0)))
self.entry.set_width_chars(5)
self.entry.set_property('activates_default', True)
self.widget.pack_start(self.entry, True, True)
self.widget.show_all()
def _value_get(self):
value = self.widget.get_text()
if value:
return [(self.name, self.attrs.get('comparator', 'ilike'), value)]
value = self.entry.get_text()
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if value or oper != 'ilike':
if oper == '=' and not value:
value = False
return [(self.name, oper, value)]
else:
return []
def _value_set(self, value):
self.widget.set_text(value or '')
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
self.entry.set_text(value[1] or '')
value = property(_value_get, _value_set)
def clear(self):
self.value = ''
self.value = ['ilike', '']
def _readonly_set(self, value):
self.widget.set_editable(not value)
self.widget.set_sensitive(not value)
self.combo.set_sensitive(not value)
self.entry.set_editable(not value)
self.entry.set_sensitive(not value)
def sig_activate(self, fct):
self.widget.connect_after('activate', fct)
self.entry.connect_after('activate', fct)
@@ -28,6 +28,7 @@ class CheckBox(Interface):
completion.set_model(self.widget.get_model())
self.widget.child.set_completion(completion)
completion.set_text_column(0)
self.widget.show()
def sig_key_press(self, widget, event):
if event.type == gtk.gdk.KEY_PRESS \
@@ -33,13 +33,24 @@ class Float(Integer):
else:
return locale.format('%.' + str(self.digits[1]) + 'f',
value or 0.0, True)
self.entry1.set_text(conv(value[0]))
self.entry2.set_text(conv(value[0]))
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
self.entry1.set_text(conv(value[1]))
if len(value) == 2:
self.entry2.set_text('')
else:
self.entry2.set_text(conv(value[2]))
value = property(_value_get, _value_set)
def clear(self):
self.value = (False, False)
self.value = ('=', False, False)
def sig_insert_text(self, widget, new_text, new_text_length, position):
value = widget.get_text()
@@ -21,6 +21,7 @@ class _container(object):
def new(self, col=8):
self.col = col+1
table = gtk.Table(1, col)
table.show()
table.set_homogeneous(False)
table.set_col_spacings(3)
table.set_row_spacings(0)
@@ -49,7 +50,9 @@ class _container(object):
(table, i, j) = self.cont[-1]
if name:
vbox = gtk.VBox(homogeneous=False, spacing=1)
vbox.show()
label = gtk.Label(name)
label.show()
label.set_alignment(0.0, 0.5)
vbox.pack_start(label, expand=False)
vbox.pack_start(widget, expand=expand, fill=True)
@@ -81,7 +84,9 @@ class Parse(object):
self.add_widget_end = []
self.container = None
self.spin_limit = gtk.SpinButton(climb_rate=1, digits=0)
self.spin_limit.show()
self.spin_offset = gtk.SpinButton(climb_rate=1, digits=0)
self.spin_offset.show()
self.title = 'Form'
self.notebooks = []
self.dict_widget = {}
@@ -143,6 +148,7 @@ class Parse(object):
hb_param.pack_start(self.spin_offset, expand=False, fill=False)
hb_param.show_all()
return hb_param
def _psr_end(self, name):
@@ -161,10 +167,13 @@ class Parse(object):
psr.Parse(xml_data)
vbox = gtk.VBox()
vbox.show()
vbox.pack_start(self.container.pop())
expander = gtk.Expander(_('Advanced Search'))
expander.show()
vbox2 = gtk.VBox()
vbox2.show()
self.container = _container(max_width)
self.container.new(self.col)
@@ -175,7 +184,6 @@ class Parse(object):
vbox2.pack_start(self.container.pop())
vbox2.pack_start(self.add_parameters())
vbox2.show_all()
expander.add(vbox2)
vbox.pack_start(expander)
@@ -199,7 +207,7 @@ class Form(object):
if self.parent:
width = self.parent.size_request()[0]
(self.widgets, self.widget) = parser.parse(xml, width)
self.widget.show_all()
self.widget.show()
self.spin_limit = parser.spin_limit
self.spin_limit.connect('value-changed', self.limit_changed)
self.spin_limit.set_activates_default(True)
@@ -3,6 +3,7 @@ import gtk
from interface import Interface
import locale
import gettext
import gobject
_ = gettext.gettext
@@ -12,6 +13,22 @@ class Integer(Interface):
def __init__(self, name, parent, attrs=None):
super(Integer, self).__init__(name, parent, attrs=attrs)
self.widget = gtk.HBox(spacing=3)
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.combo = gtk.ComboBox(self.liststore)
cell = gtk.CellRendererText()
self.combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 1)
for oper in (['=', _('equal')],
['between', _('between')],
['not between', _('not between')],
['!=', _('not equal')],
):
self.liststore.append(oper)
self.combo.set_active(0)
self.widget.pack_start(self.combo, False, False)
self.combo.connect('changed', self._changed)
self.entry1 = gtk.Entry()
self.entry1.set_max_length(0)
self.entry1.set_width_chars(5)
@@ -19,7 +36,8 @@ class Integer(Interface):
self.entry1.set_alignment(1.0)
self.entry1.connect('insert_text', self.sig_insert_text)
self.widget.pack_start(self.entry1, expand=False, fill=True)
self.widget.pack_start(gtk.Label('-'), expand=False, fill=False)
self.separator = gtk.Label('-')
self.widget.pack_start(self.separator, expand=False, fill=False)
self.entry2 = gtk.Entry()
self.entry2.set_max_length(0)
self.entry2.set_width_chars(5)
@@ -28,6 +46,18 @@ class Integer(Interface):
self.entry2.connect('insert_text', self.sig_insert_text)
self.widget.pack_start(self.entry2, expand=False, fill=True)
self.widget.show_all()
self._changed(self.combo)
def _changed(self, widget):
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if oper in ('=', '!='):
self.entry2.hide()
self.separator.hide()
else:
self.entry2.show()
self.separator.show()
def _value_get(self):
try:
value1 = locale.atoi(self.entry1.get_text())
@@ -40,19 +70,25 @@ class Integer(Interface):
return self._get_clause(value1, value2)
def _get_clause(self, value1, value2):
res = []
if value1 > value2:
if value2 != 0:
res.append((self.name, '>=', value2))
res.append((self.name, '<=', value1))
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if oper in ('=', '!='):
if self.entry1.get_text():
return [(self.name, oper, value1)]
else:
res.append((self.name, '>=', value1))
elif value1 < value2:
res.append((self.name, '>=', value1))
res.append((self.name, '<=', value2))
elif value1 == value2 and value1 != 0:
res.append((self.name, '=', value1))
return res
return []
else:
res = []
if oper == 'between':
oper1 = '>='
oper2 = '<='
else:
oper1 = '<='
oper2 = '>='
if value1:
res.append((self.name, oper1, value1))
if value2:
res.append((self.name, oper2, value2))
return res
def _value_set(self, value):
def conv(value):
@@ -60,13 +96,24 @@ class Integer(Interface):
return ''
else:
return locale.format('%d', value or 0, True)
self.entry1.set_text(conv(value[0]))
self.entry2.set_text(conv(value[1]))
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
self.entry1.set_text(conv(value[1]))
if len(value) == 2:
self.entry2.set_text('')
else:
self.entry2.set_text(conv(value[2]))
value = property(_value_get, _value_set)
def clear(self):
self.value = (False, False)
self.value = ('=', False, False)
def sig_activate(self, fct):
self.entry1.connect_after('activate', fct)
@@ -4,6 +4,7 @@ import gettext
from interface import Interface
import tryton.rpc as rpc
import tryton.common as common
import gobject
_ = gettext.gettext
@@ -14,8 +15,26 @@ class Reference(Interface):
if attrs is None:
attrs = {}
super(Reference, self).__init__(name, parent, attrs)
self.widget = gtk.combo_box_entry_new_text()
self.widget.child.set_editable(False)
self.widget = gtk.HBox()
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.combo = gtk.ComboBox(self.liststore)
cell = gtk.CellRendererText()
self.combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 1)
for oper in (['like', _('equal')],
['not like', _('different')],
):
self.liststore.append(oper)
self.combo.set_active(0)
self.widget.pack_start(self.combo, False, False)
self.entry = gtk.combo_box_entry_new_text()
self.entry.child.set_editable(True)
self.entry.child.set_property('activates_default', True)
self.entry.child.connect('key_press_event', self.sig_key_press)
self.entry.set_focus_chain([self.entry.child])
self._selection = {}
selection = attrs.get('selection', [])
if 'relation' in attrs:
@@ -37,41 +56,70 @@ class Reference(Interface):
selection.sort(lambda x, y: cmp(x[1], y[1]))
attrs['selection'] = selection
self.set_popdown(selection)
def get_model(self):
res = self.widget.child.get_text()
return self._selection.get(res, False)
self.widget.pack_start(self.entry, True, True)
self.widget.show_all()
def set_popdown(self, selection):
model = self.widget.get_model()
model = self.entry.get_model()
model.clear()
lst = []
for (i, j) in selection:
name = str(j)
if type(i) == type(1):
name += ' ('+str(i)+')'
name += ' (' + str(i) + ')'
lst.append(name)
self._selection[name] = i
self.widget.append_text('')
self.entry.append_text('')
for name in lst:
self.widget.append_text(name)
self.entry.append_text(name)
completion = gtk.EntryCompletion()
#Only available in PyGTK 2.6 and above.
if hasattr(completion, 'set_inline_selection'):
completion.set_inline_selection(True)
completion.set_model(model)
self.entry.child.set_completion(completion)
completion.set_text_column(0)
return lst
def sig_key_press(self, widget, event):
if event.type == gtk.gdk.KEY_PRESS \
and event.state & gtk.gdk.CONTROL_MASK \
and event.keyval == gtk.keysyms.space:
self.entry.popup()
def _value_get(self):
if self.get_model():
return [(self.name, 'like', self.get_model() + ',')]
value = self._selection.get(self.entry.child.get_text(), False)
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if value or oper != 'like':
return [(self.name, oper, value + ',')]
else:
self.entry.child.set_text('')
return []
def _value_set(self, value):
if value == False:
value = ''
for sel in self._selection:
if self._selection[sel] == value:
self.widget.child.set_text(sel)
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
if value[1] == False:
self.entry.child.set_text('')
return
for long_text, sel_value in self._selection.items():
if sel_value == value[1]:
self.entry.child.set_text(long_text)
break
value = property(_value_get, _value_set)
value = property(_value_get, _value_set, None,
'The content of the widget or ValueError if not valid')
def clear(self):
self.value = ''
self.value = ['like', False]
def _readonly_set(self, value):
self.combo.set_sensitive(not value)
self.entry.set_sensitive(not value)
def sig_activate(self, fct):
self.entry.child.connect_after('activate', fct)
@@ -3,6 +3,7 @@ import gtk
from interface import Interface
import tryton.rpc as rpc
import tryton.common as common
import gobject
class Selection(Interface):
@@ -11,11 +12,25 @@ class Selection(Interface):
attrs = {}
super(Selection, self).__init__(name, parent, attrs)
self.widget = gtk.combo_box_entry_new_text()
self.widget.child.set_editable(True)
self.widget.child.set_property('activates_default', True)
self.widget.child.connect('key_press_event', self.sig_key_press)
self.widget.set_focus_chain([self.widget.child])
self.widget = gtk.HBox()
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
self.combo = gtk.ComboBox(self.liststore)
cell = gtk.CellRendererText()
self.combo.pack_start(cell, True)
self.combo.add_attribute(cell, 'text', 1)
for oper in (['=', _('equal')],
['!=', _('different')],
):
self.liststore.append(oper)
self.combo.set_active(0)
self.widget.pack_start(self.combo, False, False)
self.entry = gtk.combo_box_entry_new_text()
self.entry.child.set_editable(True)
self.entry.child.set_property('activates_default', True)
self.entry.child.connect('key_press_event', self.sig_key_press)
self.entry.set_focus_chain([self.entry.child])
self._selection = {}
selection = attrs.get('selection', [])
if 'relation' in attrs:
@@ -37,9 +52,11 @@ class Selection(Interface):
selection.sort(lambda x, y: cmp(x[1], y[1]))
attrs['selection'] = selection
self.set_popdown(selection)
self.widget.pack_start(self.entry, True, True)
self.widget.show_all()
def set_popdown(self, selection):
model = self.widget.get_model()
model = self.entry.get_model()
model.clear()
self._selection = {}
lst = []
@@ -49,15 +66,15 @@ class Selection(Interface):
name += ' (' + str(i) + ')'
lst.append(name)
self._selection[name] = i
self.widget.append_text('')
self.entry.append_text('')
for name in lst:
self.widget.append_text(name)
self.entry.append_text(name)
completion = gtk.EntryCompletion()
#Only available in PyGTK 2.6 and above.
if hasattr(completion, 'set_inline_selection'):
completion.set_inline_selection(True)
completion.set_model(model)
self.widget.child.set_completion(completion)
self.entry.child.set_completion(completion)
completion.set_text_column(0)
return lst
@@ -65,32 +82,41 @@ class Selection(Interface):
if event.type == gtk.gdk.KEY_PRESS \
and event.state & gtk.gdk.CONTROL_MASK \
and event.keyval == gtk.keysyms.space:
self.widget.popup()
self.entry.popup()
def _value_get(self):
res = self._selection.get(self.widget.child.get_text(), False)
if res:
return [(self.name, '=', res)]
self.widget.child.set_text('')
return []
value = self._selection.get(self.entry.child.get_text(), False)
oper = self.liststore.get_value(self.combo.get_active_iter(), 0)
if value or oper != '=':
return [(self.name, oper, value)]
else:
self.entry.child.set_text('')
return []
def _value_set(self, value):
if value == False:
self.widget.child.set_text('')
i = self.liststore.get_iter_root()
while i:
if self.liststore.get_value(i, 0) == value[0]:
self.combo.set_active_iter(i)
break
i = self.liststore.iter_next(i)
if value[1] == False:
self.entry.child.set_text('')
return
for long_text, sel_value in self._selection.items():
if sel_value == value:
self.widget.child.set_text(long_text)
if sel_value == value[1]:
self.entry.child.set_text(long_text)
break
def clear(self):
self.value = False
self.value = ['=', False]
value = property(_value_get, _value_set, None,
'The content of the widget or ValueError if not valid')
def _readonly_set(self, value):
self.widget.set_sensitive(not value)
self.combo.set_sensitive(not value)
self.entry.set_sensitive(not value)
def sig_activate(self, fct):
self.widget.child.connect_after('activate', fct)
self.entry.child.connect_after('activate', fct)