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

Reply via email to