Anup (Open ERP) 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,
I have made implementations for supporting '|'(OR) and '&'(AND) in attrs.
Refactored the code with python operator module.
Thanks.
--
https://code.launchpad.net/~openerp-commiter/openobject-client/trunk-ach-branch/+merge/29991
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-07-02 06:34:07 +0000
+++ bin/tools/__init__.py 2010-07-15 13:47:00 +0000
@@ -22,6 +22,7 @@
import time
import datetime
import os
+import operator
import logging
if os.name == 'nt':
@@ -75,38 +76,66 @@
return result
#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:
- return True
- elif con[1].lower()=="not in":
- for cond in con[2]:
- if val == cond:
- return False
- return True
- return False
-
+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):
+ OPERATORS = {'=': getattr(operator, 'eq'),
+ '!=': getattr(operator, 'ne'),
+ '<': getattr(operator, 'lt'),
+ '>': getattr(operator, 'gt'),
+ '<=': getattr(operator, 'le'),
+ '>=': getattr(operator, 'ge'),
+ 'in': getattr(operator, 'contains'),
+ 'not in': getattr(operator, 'contains')}
+
+ OPERAND_MAPPER = {'<>': '!=', '==': '='}
+
+ def __init__(self, condition):
+ self.cond = condition
+
+ def eval(self, context):
+ if context:
+ def evaluate(cond):
+ if isinstance(cond,bool):
+ return cond
+ left, oper, right = cond
+ real_op = self.OPERAND_MAPPER.get(oper.lower(), oper)
+ if oper in ('in','not in'):
+ res = self.OPERATORS[real_op](right, context[left].get(context))
+ if oper == 'not in':
+ res = operator.not_(res)
+ else:
+ res = self.OPERATORS[real_op](context[left].get(context), right)
+
+ return res
+
+ def find_index(con):
+ index_or = index_and = -1
+ for a in range(len(con)):
+ if con[a] == '|':
+ index_or = a
+ if con[a] == '&':
+ index_and = a
+ return [index_or, index_and]
+ ind_or,ind_and = find_index(self.cond)
+ while(ind_or != -1 or ind_and != -1):
+ if ind_or > ind_and:
+ ind = ind_or
+ result = any((evaluate(self.cond[ind+1]), evaluate(self.cond[ind+2])))
+ if ind_and > ind_or:
+ ind = ind_and
+ result = all((evaluate(self.cond[ind+1]), evaluate(self.cond[ind+2])))
+ self.cond.__delslice__(ind, ind+3)
+ self.cond.__setslice__(ind, ind, [result])
+ ind_or,ind_and = find_index(self.cond)
+ res = all(evaluate(expr) for expr in self.cond)
+ 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-05-12 14:03:03 +0000
+++ bin/widget/model/field.py 2010-07-15 13:47:00 +0000
@@ -137,8 +137,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-04-13 11:34:18 +0000
+++ bin/widget/view/form.py 2010-07-15 13:47:00 +0000
@@ -433,9 +433,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-07-08 13:32:51 +0000
+++ bin/widget/view/form_gtk/parser.py 2010-07-15 13:47:00 +0000
@@ -151,18 +151,21 @@
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)
-
- if k == 'invisible':
- func = ['show', 'hide'][bool(result)]
- getattr(self.widget, func)()
- if self.label:
- getattr(self.label, func)()
- elif k == 'readonly':
- self.widget.set_sensitive(not result)
- if self.label:
- self.label.set_sensitive(not result)
+ result = result and tools.calc_condition(self, model, v)
+ if result:
+ if k=='invisible':
+ self.widget.hide()
+ if k=='readonly':
+ self.widget.set_sensitive(False)
+ else:
+ self.widget.set_sensitive(True)
+ else:
+ if k=='readonly':
+ self.widget.set_sensitive(False)
+ else:
+ self.widget.set_sensitive(True)
+ if k=='invisible':
+ self.widget.show()
class _container(object):
=== modified file 'bin/widget/view/list.py'
--- bin/widget/view/list.py 2010-07-02 08:33:04 +0000
+++ bin/widget/view/list.py 2010-07-15 13:47:00 +0000
@@ -437,8 +437,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-05-05 13:18:56 +0000
+++ bin/widget/view/tree_gtk/parser.py 2010-07-15 13:47:00 +0000
@@ -240,8 +240,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'):
@@ -643,8 +642,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 True
_______________________________________________
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