Anup (OpenERP) has proposed merging
lp:~openerp-commiter/openobject-client/trunk-ach-branch into
lp:openobject-client.
Requested reviews:
OpenERP sa GTK client R&D (openerp-dev-gtk)
Related bugs:
#491817 support for 'or' in attrs keyword
https://bugs.launchpad.net/bugs/491817
Hello
This branch contains the new created parser for attrs.
The new Parser is much more fast and efficient fulfilling all requirements.
Thanks.
--
https://code.launchpad.net/~openerp-commiter/openobject-client/trunk-ach-branch/+merge/42606
Your team OpenERP sa GTK client R&D is requested to review the proposed merge
of lp:~openerp-commiter/openobject-client/trunk-ach-branch into
lp:openobject-client.
=== modified file 'bin/tools/__init__.py'
--- bin/tools/__init__.py 2010-10-12 16:53:15 +0000
+++ bin/tools/__init__.py 2010-12-03 11:39:55 +0000
@@ -20,6 +20,7 @@
##############################################################################
import datetime
+import operator
import logging
import locale
import os
@@ -80,38 +81,77 @@
return attrs
#FIXME use spaces
-def calc_condition(self,model,con):
- if model and (con[0] in model.mgroup.fields):
- val = model[con[0]].get(model)
- if con[1]=="=" or con[1]=="==":
- if val==con[2]:
- return True
- elif con[1]=="!=" or con[1]=="<>":
- if val!=con[2]:
- return True
- elif con[1]=="<":
- if val<con[2]:
- return True
- elif con[1]==">":
- if val>con[2]:
- return True
- elif con[1]=="<=":
- if val<=con[2]:
- return True
- elif con[1]==">=":
- if val>=con[2]:
- return True
- elif con[1].lower()=="in":
- for cond in con[2]:
- if val == cond:
+def calc_condition(self, model, cond):
+ cond_main = cond[:]
+ try:
+ return ConditionExpr(cond).eval(model)
+ except:
+ import common
+ common.error('Wrong attrs Implementation!','You have wrongly specified conditions in attrs %s' %(cond_main,))
+
+class ConditionExpr(object):
+
+ OPERAND_MAPPER = {'<>': '!=', '==': '='}
+
+ def __init__(self, condition):
+ self.cond = condition
+
+ def eval(self, model):
+ if model:
+ eval_stack = [] # Stack used for evaluation
+ ops = ['=','!=','<','>','<=','>=','in','not in','<>','==']
+
+ def is_operand(cond): # Method to check the Operands
+ if (len(cond)==3 and cond[1] in ops) or isinstance(cond,bool):
return True
- elif con[1].lower()=="not in":
- for cond in con[2]:
- if val == cond:
+ else:
return False
- return True
- return False
+
+ def evaluate(cond): # Method to evaluate the conditions
+ if isinstance(cond,bool):
+ return cond
+ left, oper, right = cond
+ oper = self.OPERAND_MAPPER.get(oper.lower(), oper)
+ if oper == '=':
+ res = operator.eq(model[left].get(model),right)
+ elif oper == '!=':
+ res = operator.ne(model[left].get(model),right)
+ elif oper == '<':
+ res = operator.lt(model[left].get(model),right)
+ elif oper == '>':
+ res = operator.gt(model[left].get(model),right)
+ elif oper == '<=':
+ res = operator.le(model[left].get(model),right)
+ elif oper == '>=':
+ res = operator.ge(model[left].get(model),right)
+ elif oper == 'in':
+ res = operator.contains(right, model[left].get(model))
+ elif oper == 'not in':
+ res = operator.contains(right, model[left].get(model))
+ res = operator.not_(res)
+ return res
+ orig_stack = self.cond
+ orig_stack.reverse()
+ for condition in orig_stack:
+ if is_operand(condition): # If operand Push on Stack
+ eval_stack.append(condition)
+ elif condition in ['|','&','!']: # If operator pop necessary operands from stack and evaluate and store the result back to stack
+ if condition in ('|','&'):
+ elem_1 = eval_stack.pop()
+ elem_2 = eval_stack.pop()
+ if condition=='|':
+ result = any((evaluate(elem_1), evaluate(elem_2)))
+ else:
+ result = all((evaluate(elem_1), evaluate(elem_2)))
+ elif condition == '!':
+ elem_1 = eval_stack.pop()
+ result = not evaluate(elem_1)
+ eval_stack.append(result)
+
+ res = all(evaluate(expr) for expr in eval_stack) # evaluate all the remaining elments if any
+ return res
+
def call_log(fun):
"""Debug decorator
TODO: Add optionnal execution time
=== modified file 'bin/widget/model/field.py'
--- bin/widget/model/field.py 2010-11-16 13:11:20 +0000
+++ bin/widget/model/field.py 2010-12-03 11:39:55 +0000
@@ -138,8 +138,7 @@
attrs_changes[k][i]=cond
for k,v in attrs_changes.items():
result = True
- for condition in v:
- result = result and tools.calc_condition(self,model,condition)
+ result = tools.calc_condition(self, model, v)
if result:
self.get_state_attrs(model)[k]=True
=== modified file 'bin/widget/view/form.py'
--- bin/widget/view/form.py 2010-12-03 09:31:10 +0000
+++ bin/widget/view/form.py 2010-12-03 11:39:55 +0000
@@ -353,9 +353,7 @@
cond=v[i][0],v[i][1],v[i][2][0]
attrs_changes[k][i]=cond
for k,v in attrs_changes.items():
- result = True
- for condition in v:
- result = result and tools.calc_condition(self,model,condition)
+ result = tools.calc_condition(self, model, v)
if result:
if k=='invisible':
obj.hide()
=== modified file 'bin/widget/view/form_gtk/parser.py'
--- bin/widget/view/form_gtk/parser.py 2010-11-10 12:47:34 +0000
+++ bin/widget/view/form_gtk/parser.py 2010-12-03 11:39:55 +0000
@@ -44,7 +44,6 @@
'label': attrs.get('string', 'unknown')
}
self.widget = gtk.Button(**args)
- self.widget.set_flags(gtk.CAN_DEFAULT)
readonly = bool(int(attrs.get('readonly', '0')))
self.set_sensitive(not readonly)
@@ -120,8 +119,10 @@
elif model.validate():
id = self.form.screen.save_current()
- model.get_button_action(self.form.screen, id, self.attrs)
- self.warn('misc-message', '')
+ if not self.attrs.get('confirm',False) or \
+ common.sur(self.attrs['confirm']):
+ model.get_button_action(self.form.screen,id,self.attrs)
+ self.warn('misc-message', '')
else:
common.warning(_('Invalid form, correct red fields !'), _('Error !') )
self.warn('misc-message', _('Invalid form, correct red fields !'), "red")
@@ -135,7 +136,6 @@
self.widget = widget
self.label = label
self.states = states or []
- self.frame_child = {}
def __getattr__(self, a):
return self.widget.__getattribute__(a)
@@ -150,16 +150,16 @@
sa = getattr(self.widget, 'attrs') or {}
attrs_changes = eval(sa.get('attrs',"{}"),{'uid':rpc.session.uid})
+ if sa.get('default_focus',False):
+ self.widget.grab_focus()
for k,v in attrs_changes.items():
result = True
- for condition in v:
- result = result and tools.calc_condition(self,model,condition)
-
+ result = result and tools.calc_condition(self, model, v)
if k == 'invisible':
func = ['show', 'hide'][bool(result)]
getattr(self.widget, func)()
if self.label:
- getattr(self.label, func)()
+ getattr(self.label, func)()
elif k == 'readonly':
if isinstance(self.widget, gtk.Frame):
for name, wid in self.frame_child.iteritems():
@@ -214,20 +214,15 @@
def create_label(self, name, markup=False, align=1.0, wrap=False,
angle=None, width=None, fname=None, help=None, detail_tooltip=False):
-
label = gtk.Label(name)
+ if markup:
+ label.set_use_markup(True)
+
eb = gtk.EventBox()
eb.set_events(gtk.gdk.BUTTON_PRESS_MASK)
- if markup:
- label.set_use_markup(True)
self.trans_box_label.append((eb, name, fname))
eb.add(label)
- def size_allocate(label, allocation):
- label.set_size_request( allocation.width - 2, -1 )
- if fname is None and name and len(name) > 50:
- label.connect( "size-allocate", size_allocate )
-
uid = rpc.session.uid
tooltip = ''
if help:
@@ -238,12 +233,18 @@
tooltip += (help and '\n' or '') + detail_tooltip
if tooltip:
eb.set_tooltip_markup(tooltip)
+
+
label.set_alignment(align, 0.5)
+
if width:
label.set_size_request(width, -1)
+
label.set_line_wrap(bool(int(wrap)))
if angle:
label.set_angle(int(angle))
+
+
return eb
def wid_add(self, widget, label=None, xoptions=False, expand=False, ypadding=2, rowspan=1,
@@ -306,9 +307,7 @@
super(parser_form, self).__init__(window, parent=parent, attrs=attrs,
screen=screen)
self.widget_id = 0
- self.default_focus_field = False
- self.default_focus_button = False
- self.accepted_attr_list = ['type','domain','context','relation', 'widget','attrs',
+ self.accepted_attr_list = ['type','domain','context','relation', 'widget',
'digits','function','store','fnct_search','fnct_inv','fnct_inv_arg',
'func_obj','func_method','related_columns','third_table','states',
'translate','change_default','size','selection']
@@ -399,13 +398,7 @@
visval = eval(attrs['invisible'], {'context':self.screen.context})
if visval:
continue
-
- if 'default_focus' in attrs and not self.default_focus_button:
- attrs['focus_button'] = attrs['default_focus']
- self.default_focus_button = True
-
button = Button(attrs)
-
states = [e for e in attrs.get('states','').split(',') if e]
saw_list.append(StateAwareWidget(button, states=states))
container.wid_add(button.widget, colspan=int(attrs.get('colspan', 1)))
@@ -522,8 +515,7 @@
visval = eval(attrs['invisible'], {'context':self.screen.context})
if visval:
continue
- state_aware = StateAwareWidget(frame, states=states)
- saw_list.append(state_aware)
+ saw_list.append(StateAwareWidget(frame, states=states))
if attrs.get("width",False) or attrs.get("height"):
frame.set_size_request(int(attrs.get('width', -1)) ,int(attrs.get('height', -1)))
@@ -535,7 +527,6 @@
container.wid_add(group_wid, colspan=int(attrs.get('colspan', 1)), expand=int(attrs.get('expand',0)), rowspan=int(attrs.get('rowspan', 1)), ypadding=0, fill=int(attrs.get('fill', 1)))
container.new(int(attrs.get('col',4)))
widget, widgets, saws, on_write = self.parse(model, node, fields)
- state_aware.frame_child.update(widgets)
dict_widget.update(widgets)
saw_list += saws
frame.add(widget)
=== modified file 'bin/widget/view/list.py'
--- bin/widget/view/list.py 2010-12-03 11:17:56 +0000
+++ bin/widget/view/list.py 2010-12-03 11:39:55 +0000
@@ -474,8 +474,7 @@
attrs_changes = eval(path.attrs.get('attrs',"{}"),{'uid':rpc.session.uid})
for k,v in attrs_changes.items():
result = True
- for condition in v:
- result = tools.calc_condition(self,model,condition)
+ result = tools.calc_condition(self,model,v)
if result:
if k=='invisible':
return False
=== modified file 'bin/widget/view/tree_gtk/parser.py'
--- bin/widget/view/tree_gtk/parser.py 2010-11-26 11:24:56 +0000
+++ bin/widget/view/tree_gtk/parser.py 2010-12-03 11:39:55 +0000
@@ -245,8 +245,7 @@
attrs_changes = eval(self.attrs.get('attrs',"{}"),{'uid':rpc.session.uid})
for k,v in attrs_changes.items():
result = False
- for condition in v:
- result = tools.calc_condition(self,model,condition)
+ result = tools.calc_condition(self,model,v)
model[self.field_name].get_state_attrs(model)[k] = result
def state_set(self, model, state='draft'):
@@ -657,8 +656,7 @@
attrs_changes = eval(self.attrs.get('attrs',"{}"),{'uid':rpc.session.uid})
for k,v in attrs_changes.items():
result = False
- for condition in v:
- result = tools.calc_condition(self,model,condition)
+ result = tools.calc_condition(self,model,v)
if result:
if k == 'invisible':
return 'hide'
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp