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

Reply via email to