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

Reply via email to