Anup (OpenERP) has proposed merging
lp:~openerp-commiter/openobject-client/trunk-ach-branch into
lp:openobject-client.
Requested reviews:
Olivier Dony (OpenERP) (odo)
tfr (Openerp) (tfr)
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 the changes suggested by tfr(OpenERP) and have made a single
stack instead of two.
I have also made changes suggested by RGA(OpenERP) as followed,
I have added a condition to check if the field exists in the model or not.
I have added translation for the message.
Thanks.
--
https://code.launchpad.net/~openerp-commiter/openobject-client/trunk-ach-branch/+merge/44435
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/po/openerp-client.pot'
--- bin/po/openerp-client.pot 2010-12-13 17:15:27 +0000
+++ bin/po/openerp-client.pot 2010-12-22 08:46:10 +0000
@@ -17,6 +17,22 @@
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+#: bin/tools/__init__.py:90
+msgid "Wrong attrs Implementation!"
+msgstr ""
+
+#: bin/tools/__init__.py:90
+msgid "You have wrongly specified conditions in attrs %s"
+msgstr ""
+
+#: bin/tools/__init__.py:105
+msgid "Field not found"
+msgstr ""
+
+#: bin/tools/__init__.py:105
+msgid "The Field %s does not exist in the view"
+msgstr ""
+
#: bin/plugins/__init__.py:27
msgid "Print Workflow"
msgstr ""
=== modified file 'bin/tools/__init__.py'
--- bin/tools/__init__.py 2010-10-12 16:53:15 +0000
+++ bin/tools/__init__.py 2010-12-22 08:46:10 +0000
@@ -20,6 +20,7 @@
##############################################################################
import datetime
+import operator
import logging
import locale
import os
@@ -80,38 +81,88 @@
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:
- return True
- elif con[1].lower()=="not in":
- for cond in con[2]:
- if val == cond:
- 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):
+
+ OPERAND_MAPPER = {'<>': '!=', '==': '='}
+
+ def __init__(self, condition):
+ self.cond = condition
+ self.check_condition(self.cond)
+
+ def check_condition(self, con):
+ for element in cond:
+ if self.is_leaf(element):
+ left,opr,right = element
+ if not model.get(left,False):
+ common.error(_('Field not found'),_('The Field %s does not exist in the view') %(left,))
+
+ ops = ['=','!=','<','>','<=','>=','in','not in','<>','==']
+
+ def is_leaf(self,cond): # Method to check the Operands
+ if (len(cond)==3 and cond[1] in ops) or isinstance(cond,bool):
return True
- return False
+ else:
+ return False
+
+ def eval(self, model):
+ if model:
+ eval_stack = [] # Stack used for evaluation
+
+ 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
+ eval_stack = self.cond[:]
+ eval_stack.reverse()
+
+ while len(eval_stack) > 1:
+ condition = eval_stack.pop()
+ if self.is_leaf(condition): # If operand Push on Stack
+ eval_stack.append(condition)
+ eval_stack.append('&') #by default it's a and
+ 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-12-06 11:11:51 +0000
+++ bin/widget/model/field.py 2010-12-22 08:46:10 +0000
@@ -143,8 +143,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 15:04:54 +0000
+++ bin/widget/view/form.py 2010-12-22 08:46:10 +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-22 08:46:10 +0000
@@ -152,9 +152,7 @@
attrs_changes = eval(sa.get('attrs',"{}"),{'uid':rpc.session.uid})
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)()
@@ -214,7 +212,7 @@
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)
eb = gtk.EventBox()
eb.set_events(gtk.gdk.BUTTON_PRESS_MASK)
@@ -222,12 +220,11 @@
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:
@@ -399,13 +396,13 @@
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)))
=== modified file 'bin/widget/view/list.py'
--- bin/widget/view/list.py 2010-12-13 12:54:46 +0000
+++ bin/widget/view/list.py 2010-12-22 08:46:10 +0000
@@ -497,8 +497,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-29 20:37:53 +0000
+++ bin/widget/view/tree_gtk/parser.py 2010-12-22 08:46:10 +0000
@@ -266,8 +266,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'):
@@ -678,8 +677,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