def parse(self, root, fields):
        self.node_flds['visible'] = []
        self.node_flds['invisible'] = []

        for node in root.childNodes:
            if node.nodeName == 'node':
                attrs = node_attributes(node)
                self.node = attrs['object']
                self.bgcolor = attrs.get('bgcolor', '')
                self.shapes = attrs.get('shape', '')

                for fld in node.childNodes:
                    if fld.nodeName == 'field':
                        attrs = node_attributes(fld)
                        name = attrs['name']
                        if attrs.has_key('invisible') and attrs['invisible']=='1':
                            self.node_flds['invisible'].append(name)
                        else:
                            self.node_flds['visible'].append(name)
                            self.node_flds_string.append(fields[name].get('string', name.title()))
            elif node.nodeName == 'arrow':
                attrs = node_attributes(node)
                self.connector = attrs['object']
                self.src_node = attrs['source']
                self.des_node = attrs['destination']

                for fld in node.childNodes:
                    if fld.nodeName == 'field':
                        name = node_attributes(fld)['name']
                        self.conn_flds_string.append(fields[name].get('string', name.title()))
                        self.conn_flds.append(str(name))
Beispiel #2
0
    def parse(self, root, fields):

        info_fields = []
        attrs = node_attributes(root)

        for node in root.childNodes:
            attrs = node_attributes(node)

            if node.localName == 'field':
                info_fields += [attrs['name']]

        return info_fields
Beispiel #3
0
    def parse(self, root, fields):

        info_fields = []
        attrs = node_attributes(root)

        for node in root.childNodes:
            attrs = node_attributes(node)

            if node.localName == "field":
                info_fields += [attrs["name"]]

        return info_fields
Beispiel #4
0
    def parse(self, root, fields):

        info_fields = []
        attrs = node_attributes(root)

        for node in root.childNodes:
            attrs = node_attributes(node)

            if node.localName == 'field':
                info_fields.append(attrs['name'])

            if node.localName == 'level':
                self.level = attrs
                info_fields += self.parse(node, fields)

        return info_fields
    def parse(self, root, fields):

        info_fields = []
        attrs = node_attributes(root)

        for node in root.childNodes:
            attrs = node_attributes(node)

            if node.localName == 'field':
                info_fields.append(attrs['name'])

            if node.localName == 'level':
                self.level = attrs
                info_fields += self.parse(node, fields)

        return info_fields
Beispiel #6
0
    def parse(self, root=None, model=None, view_id=False, view_type='form'):

        result = []

        for node in root.childNodes:

            if not node.nodeType==node.ELEMENT_NODE:
                continue

            attrs = utils.node_attributes(node)

            view_id = attrs.get('view_id', view_id)
            view_type = attrs.get('view_type', view_type)

            children = []

            if node.childNodes:
                children = self.parse(node, model=model, view_id=view_id, view_type=view_type)

            node_instance = self.get_node_instance(node, model=model, view_id=view_id, view_type=view_type)
            node_instance.children = children

            result.append(node_instance)

        return result
Beispiel #7
0
    def __init__(self, model, view=False, view_id=False, ids=[], domain=[], context={},view_mode=[], group_by=[], width=360, height=300):

        name = 'graph_%s' % (random.randint(0,10000))
        super(Graph, self).__init__(name=name, model=model, width=width, height=height)

        ctx = rpc.get_session().context.copy()
        ctx.update(context or {})
        view = view or cache.fields_view_get(model, view_id, 'graph', ctx)

        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.string = attrs.get('string')
        self.group_by = group_by
        chart_type = attrs.get('type', 'pie')

        self.ids = ids

        if chart_type == "bar":
            self.data = BarChart(model, view, view_id, ids, domain, view_mode, context, group_by)
        else:
            self.data = PieChart(model, view, view_id, ids, domain, view_mode, context, group_by)

        self.data = simplejson.dumps(self.data.get_data())
Beispiel #8
0
    def parse(self, root=None, model=None, view_id=False, view_type='form'):

        result = []

        for node in root.childNodes:

            if not node.nodeType == node.ELEMENT_NODE:
                continue

            attrs = utils.node_attributes(node)

            view_id = attrs.get('view_id', view_id)
            view_type = attrs.get('view_type', view_type)

            children = []

            if node.childNodes:
                children = self.parse(node,
                                      model=model,
                                      view_id=view_id,
                                      view_type=view_type)

            node_instance = self.get_node_instance(node,
                                                   model=model,
                                                   view_id=view_id,
                                                   view_type=view_type)
            node_instance.children = children

            result.append(node_instance)

        return result
Beispiel #9
0
    def create_form(self, params, tg_errors=None):

        params.id = params.o2m_id
        params.model = params.o2m_model
        params.view_mode = ['form', 'tree']
        params.view_type = 'form'

        #XXX: dirty hack to fix bug #401700
        if not params.get('_terp_view_ids'):
            params['_terp_view_ids'] = []

        # to get proper view, first generate form using the view_params
        vp = params.view_params

        form = tw.form_view.ViewForm(vp, name="view_form", action="/openerp/openo2m/save")
        cherrypy.request.terp_validators = {}

        if '/' in params.o2m:
            params.o2m = '.'.join(params.o2m.split('/')[-1:])

        wid = form.screen.widget.get_widgets_by_name(params.o2m)[0]

        # save view_params for later phazes
        vp = vp.make_plain('_terp_view_params/')
        hiddens = map(lambda x: tw.form.Hidden(name=x, default=ustr(vp[x])), vp)

        params.prefix = params.o2m
        params.views = wid.view
        params.hide_new_button = False

        ctx = params.context or {}
        ctx.update(params.parent_context or {})
        ctx.update(params.o2m_context or {})
        p, ctx = TinyDict.split(ctx)
        
        if ctx.get('default_name'):
            del ctx['default_name']

        arch = params.views.get('form', {}).get('arch', False)
        if arch:
            dom = xml.dom.minidom.parseString(arch.encode('utf-8'))
            form_attribute = node_attributes(dom.childNodes[0])
            if form_attribute.get('hide_new_button'):
                params.hide_new_button = expr_eval(form_attribute.get('hide_new_button', False), {'context': ctx})

        params.context = ctx or {}
        params.hidden_fields = [tw.form.Hidden(name='_terp_parent_model', default=params.parent_model),
                                tw.form.Hidden(name='_terp_parent_id', default=params.parent_id),
                                tw.form.Hidden(name='_terp_parent_context', default=ustr(params.parent_context)),
                                tw.form.Hidden(name='_terp_o2m', default=params.o2m),
                                tw.form.Hidden(name='_terp_o2m_id', default=params.id or None),
                                tw.form.Hidden(name='_terp_o2m_model', default=params.o2m_model),
                                tw.form.Hidden(name='_terp_o2m_context', default=ustr(params.o2m_context or {})),
                                tw.form.Hidden(name=params.prefix + '/__id', default=params.id or None)] + hiddens

        form = tw.form_view.ViewForm(params, name="view_form", action="/openerp/openo2m/save")
        form.screen.string = wid.screen.string

        return form
Beispiel #10
0
    def view_using_sum_attrs(self, root):
        """ detect if supplied view is using <field sum=""/>

        @return: True/False
        """
        for node in root.childNodes:
            if node.nodeName == 'field' and 'attrs' in node_attributes(node):
                return True
        return False
Beispiel #11
0
    def view_using_sum_attrs(self, root):
        """ detect if supplied view is using <field sum=""/>

        @return: True/False
        """
        for node in root.childNodes:
            if node.nodeName == 'field' and 'attrs' in node_attributes(node):
                return True
        return False
Beispiel #12
0
    def save(self, _terp_what, view_id, xpath_expr, **kw):

        view_id = int(view_id)

        proxy = rpc.RPCProxy('ir.ui.view')
        res = proxy.read([view_id], ['model', 'type', 'arch'])[0]

        model = res['model']
        view_type = res['type']

        doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8'))
        node = utils.xml_locate(xpath_expr, doc)[0]

        new_node = None
        record = None

        if _terp_what == "properties":

            attrs = utils.node_attributes(node)
            for attr in attrs:
                node.removeAttribute(attr)

            for attr, val in kw.items():
                if val:
                    node.setAttribute(attr, val)

        elif _terp_what == "node" and node.parentNode:

            new_node = doc.createElement(kw['node'])

            if new_node.localName == "field":
                new_node.setAttribute('name', kw.get('name',
                                                     new_node.localName))

            elif new_node.localName == "notebook":
                page = doc.createElement('page')
                page.setAttribute('string', 'Page 1')
                new_node.appendChild(page)

            pnode = node.parentNode
            position = kw['position']

            try:

                if position == 'after':
                    pnode.insertBefore(new_node, node.nextSibling)

                if position == 'before':
                    pnode.insertBefore(new_node, node)

                if position == 'inside':
                    node.appendChild(new_node)

            except Exception, e:
                return dict(error=ustr(e))
Beispiel #13
0
    def save(self, _terp_what, view_id, xpath_expr, **kw):

        view_id = int(view_id)

        proxy = rpc.RPCProxy('ir.ui.view')
        res = proxy.read([view_id], ['model', 'type', 'arch'])[0]

        model = res['model']
        view_type = res['type']

        doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8'))
        node = utils.xml_locate(xpath_expr, doc)[0]

        new_node = None
        record = None

        if _terp_what == "properties":

            attrs = utils.node_attributes(node)
            for attr in attrs:
                node.removeAttribute(attr)

            for attr, val in kw.items():
                if val:
                    node.setAttribute(attr, val)

        elif _terp_what == "node" and node.parentNode:

            new_node = doc.createElement(kw['node'])

            if new_node.localName == "field":
                new_node.setAttribute('name', kw.get('name', new_node.localName))

            elif new_node.localName == "notebook":
                page = doc.createElement('page')
                page.setAttribute('string', 'Page 1')
                new_node.appendChild(page)

            pnode = node.parentNode
            position = kw['position']

            try:

                if position == 'after':
                    pnode.insertBefore(new_node, node.nextSibling)

                if position == 'before':
                    pnode.insertBefore(new_node, node)

                if position == 'inside':
                    node.appendChild(new_node)

            except Exception, e:
                return dict(error=ustr(e))
Beispiel #14
0
    def __init__(self, prefix, model, view, ids=[], domain=[], context=None, editable=True, readonly=False, nodefault=False, nolinks=1):

        super(Form, self).__init__(prefix=prefix, model=model, editable=editable, readonly=readonly, nodefault=nodefault)
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)
        fields = view['fields']
        self.string = attrs.get('string', '')
        self.link = attrs.get('link', nolinks)
        self.model = model
        self.id = None

        proxy = rpc.RPCProxy(model)

        self.context = dict(rpc.get_session().context,
                                **(context or {}))
        self.context['bin_size'] = True

        values = {}
        defaults = {}
        try:
            if ids:
                lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], self.context)
                if lval:
                    values = lval[0]
                    self.id = ids[0]
                    
                    for f in fields:
                        if fields[f]['type'] == 'many2one' and isinstance(values[f], tuple):
                            values[f] = values[f][0]
                            
                    ConcurrencyInfo.update(self.model, [values])

            elif 'datas' in view: # wizard data

                for f in fields:
                    if 'value' in fields[f]:
                        values[f] = fields[f]['value']

                values.update(view['datas'])

            elif not self.nodefault: # default
                defaults = self.get_defaults(fields, domain, self.context)

            elif 'state' in fields: # if nodefault and state get state only
                defaults = proxy.default_get(['state'], self.context)

            elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects)
                defaults = proxy.default_get(['x_state'], self.context)

        except Exception,e:
            raise common.warning(e)
Beispiel #15
0
    def parse(self, root, fields=None):

        for node in root.childNodes:

            if not node.nodeType==node.ELEMENT_NODE:
                continue

            attrs = node_attributes(node)

            field = fields.get(attrs['name'])
            if field and not attrs.get('invisible'):
                field.update(attrs)
                self.headers.append(field)
Beispiel #16
0
    def parse(self, root, fields=None):

        for node in root.childNodes:

            if not node.nodeType==node.ELEMENT_NODE:
                continue

            attrs = node_attributes(node)

            field = fields.get(attrs['name'])
            if field and not attrs.get('invisible'):
                field.update(attrs)
                self.headers.append(field)
    def __init__(self, name, model, view,
                 ids=None, domain=None, context=None, **kw):
        super(Diagram, self).__init__(name=name, model=model, ids=ids)

        if ids:
            self.dia_id = ids[0]

        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.string = attrs.get('string')

        self.parse(root, view['fields'])
Beispiel #18
0
    def parse(root, fields):

        for node in root.childNodes:

            if node.nodeName in ('form', 'notebook', 'page', 'group', 'tree', 'hpaned', 'vpaned'):
                parse(node, fields)

            elif node.nodeName=='field':
                attrs = node_attributes(node)
                name = attrs['name']

                fields[name].update(attrs)

        return fields
    def __init__(self, prefix, model, view, ids=[], domain=[], context=None, editable=True, readonly=False, nodefault=False, nolinks=1):

        super(Form, self).__init__(prefix=prefix, model=model, editable=editable, readonly=readonly, nodefault=nodefault)
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)
        fields = view['fields']
        self.string = attrs.get('string', '')
        self.link = attrs.get('link', nolinks)
        self.model = model
        self.id = None

        proxy = rpc.RPCProxy(model)

        self.context = dict(rpc.session.context,
                                **(context or {}))
        self.context['bin_size'] = True

        values = {}
        defaults = {}
        try:
            if ids:
                lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], self.context)
                if lval:
                    values = lval[0]
                    self.id = ids[0]
                    
                            
                    ConcurrencyInfo.update(self.model, [values])

            elif 'datas' in view: # wizard data

                for f in fields:
                    if 'value' in fields[f]:
                        values[f] = fields[f]['value']

                values.update(view['datas'])

            elif not self.nodefault: # default
                defaults = self.get_defaults(fields, domain, self.context)

            elif 'state' in fields: # if nodefault and state get state only
                defaults = proxy.default_get(['state'], self.context)

            elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects)
                defaults = proxy.default_get(['x_state'], self.context)

        except Exception,e:
            raise common.warning(e)
Beispiel #20
0
def get_calendar(model, view, ids=None, domain=[], context={}, options=None):

    mode = (options or None) and options.mode
    if not mode:
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        attrs = node_attributes(dom.childNodes[0])
        mode = attrs.get('mode')

    if mode == 'day':
        return DayCalendar(model, view, ids, domain, context, options)

    if mode == 'week':
        return WeekCalendar(model, view, ids, domain, context, options)

    return MonthCalendar(model, view, ids, domain, context, options)
def get_calendar(model, view, ids=None, domain=[], context={}, options=None):

    mode = (options or None) and options.mode
    if not mode:
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        attrs = node_attributes(dom.childNodes[0])
        mode = attrs.get('mode')

    if mode == 'day':
        return DayCalendar(model, view, ids, domain, context, options)

    if mode == 'week':
        return WeekCalendar(model, view, ids, domain, context, options)

    return MonthCalendar(model, view, ids, domain, context, options)
Beispiel #22
0
    def parse(root, fields):

        for node in root.childNodes:

            if node.nodeName in ('form', 'notebook', 'page', 'group', 'tree',
                                 'hpaned', 'vpaned'):
                parse(node, fields)

            elif node.nodeName == 'field':
                attrs = node_attributes(node)
                name = attrs['name']

                fields[name].update(attrs)

        return fields
Beispiel #23
0
    def edit(self, view_id, xpath_expr):
        view_id = int(view_id)

        proxy = rpc.RPCProxy('ir.ui.view')
        res = proxy.read([view_id], ['model', 'arch'])[0]

        doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8'))
        field = utils.xml_locate(xpath_expr, doc)[0]

        attrs = utils.node_attributes(field)
        editors = []

        properties = _PROPERTIES.get(field.localName, [])
        if field.localName == 'field':
            kind = 'char'
            try:
                model = _get_model(field, parent_model=res['model'])
                attrs2 = cache.fields_get(model, [attrs['name']],
                                          rpc.session.context)[attrs['name']]

                attrs2.update(attrs)

                if attrs2.get('widget', False):
                    if attrs2['widget'] == 'one2many_list':
                        attrs2['widget'] = 'one2many'
                    attrs2['type'] = attrs2['widget']

                kind = attrs2.get('type', kind)
            except:
                pass
            properties = _PROPERTIES_FIELDS.get(kind) or properties
        properties = properties[:]
        properties.extend(list(set(attrs.keys()) - set(properties)))

        for prop in properties:
            if field.localName == 'action' and prop == 'name':
                ed = ActionProperty(prop, attrs.get(prop))
            elif field.localName == 'button' and prop in _PROPERTY_WIDGETS_BUTTON:
                ed = _PROPERTY_WIDGETS_BUTTON[prop](prop, attrs.get(prop))
            else:
                ed = get_property_widget(prop, attrs.get(prop))

            ed.label = prop
            editors.append(ed)

        return dict(view_id=view_id, xpath_expr=xpath_expr, editors=editors)
Beispiel #24
0
    def edit(self, view_id, xpath_expr):
        view_id = int(view_id)

        proxy = rpc.RPCProxy('ir.ui.view')
        res = proxy.read([view_id], ['model', 'arch'])[0]

        doc = xml.dom.minidom.parseString(res['arch'].encode('utf-8'))
        field = utils.xml_locate(xpath_expr, doc)[0]

        attrs = utils.node_attributes(field)
        editors = []

        properties = _PROPERTIES.get(field.localName, [])
        if field.localName == 'field':
            kind = 'char'
            try:
                model = _get_model(field, parent_model=res['model'])
                attrs2 = cache.fields_get(model, [attrs['name']], rpc.session.context)[attrs['name']]

                attrs2.update(attrs)

                if attrs2.get('widget', False):
                    if attrs2['widget']=='one2many_list':
                        attrs2['widget']='one2many'
                    attrs2['type'] = attrs2['widget']

                kind = attrs2.get('type', kind)
            except:
                pass
            properties = _PROPERTIES_FIELDS.get(kind) or properties
        properties = properties[:]
        properties.extend(list(set(attrs.keys()) - set(properties)))

        for prop in properties:
            if field.localName == 'action' and prop == 'name':
                ed = ActionProperty(prop, attrs.get(prop))
            elif field.localName == 'button' and prop in _PROPERTY_WIDGETS_BUTTON:
                ed = _PROPERTY_WIDGETS_BUTTON[prop](prop, attrs.get(prop))
            else:
                ed = get_property_widget(prop, attrs.get(prop))

            ed.label = prop
            editors.append(ed)

        return dict(view_id=view_id, xpath_expr=xpath_expr, editors=editors)
Beispiel #25
0
    def get_node_instance(self, node, model, view_id=False, view_type='form'):

        field_attrs = _get_field_attrs(node, parent_model=model)

        attrs = utils.node_attributes(node)

        view_id = attrs.get('view_id', view_id)
        view_type = attrs.get('view_type', view_type)

        attrs['view_id'] = view_id
        attrs['view_type'] = view_type

        attrs['__localName__'] = node.localName
        attrs['__id__'] = random.randrange(1, 10000)

        attrs.setdefault('name', node.localName)

        field_attrs.update(attrs)

        return _NODES.get(node.localName, Node)(field_attrs)
Beispiel #26
0
    def get_node_instance(self, node, model, view_id=False, view_type='form'):

        field_attrs = _get_field_attrs(node, parent_model=model)

        attrs = utils.node_attributes(node)

        view_id = attrs.get('view_id', view_id)
        view_type = attrs.get('view_type', view_type)

        attrs['view_id'] = view_id
        attrs['view_type'] = view_type

        attrs['__localName__'] = node.localName
        attrs['__id__'] = random.randrange(1, 10000)

        attrs.setdefault('name', node.localName)

        field_attrs.update(attrs)

        return _NODES.get(node.localName, Node)(field_attrs)
Beispiel #27
0
    def parse(self, root, fields):
        axis = []
        axis_data = {}
        axis_group = {}

        for node in root.childNodes:
            attrs = node_attributes(node)
            if node.localName == 'field':
                name = attrs['name']
                fields[name].update(attrs) # Update fields ...

                attrs['string'] = fields[name]['string']

                axis.append(ustr(name))
                axis_data[ustr(name)] =  attrs

        for i in axis_data:
            axis_data[i]['string'] = fields[i]['string']
            if axis_data[i].get('group', False):
                axis_group[i]=1
                axis.remove(i)

        return axis, axis_data, axis_group
Beispiel #28
0
    def __init__(self, model, view=False, view_id=False, ids=[], domain=[], view_mode=[], context={}, group_by=[]):

        ctx = {}
        ctx = rpc.get_session().context.copy()
        ctx.update(context)

        view = view or cache.fields_view_get(model, view_id, 'graph', ctx)
        fields = view['fields']
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.view_mode = view_mode
        self.model = model
        self.string = attrs.get('string', 'Unknown')
        self.kind = attrs.get('type', '')
        self.orientation = attrs.get('orientation', 'vertical')
        self.values = []
        self.group_by = group_by
        add_grp_field = ''
        if self.group_by and not fields.has_key(self.group_by[0]):
            add_grp_field = cache.fields_get(self.model, [self.group_by[0]], rpc.get_session().context)
            fields.update(add_grp_field)
        axis, axis_data, axis_group = self.parse(root, fields)

        if  self.group_by:
            axis[0] = self.group_by[0]
            axis_data.update(add_grp_field)
        proxy = rpc.RPCProxy(model)

        ctx = rpc.get_session().context.copy()
        ctx.update(context)
        if ids is None:
            ids = proxy.search(domain, 0, 0, 0, ctx)

        rec_ids = []
        values = proxy.read(ids, fields.keys(), ctx)

        for value in values:
            res = {}
            rec_ids.append(value.get('id'))
            res['temp_id'] = value.get('id')

            for x in axis_data.keys():
                if fields[x]['type'] in ('many2one', 'char','time','text'):
                    res[x] = value[x]
                    if isinstance(res[x], (list, tuple)):
                        res[x] = res[x][-1]
                    res[x] = ustr(res[x])
                elif fields[x]['type'] in 'selection':
                    selection_mapping = dict(fields[x]['selection'])
                    res[x] = selection_mapping.get(value[x], False)
                elif fields[x]['type'] == 'date':
                    if value[x]:
                        date = time.strptime(value[x], DT_SERVER_FORMATS['date'])
                        date = tz_convert(date, 'parse')
                        res[x] = time.strftime(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'), date)
                    else:
                        res[x] = ''
                elif fields[x]['type'] == 'datetime':
                    if value[x]:
                        date = time.strptime(value[x], DT_SERVER_FORMATS['datetime'])
                        date = tz_convert(date, 'parse')
                        res[x] = time.strftime(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')+' %H:%M:%S', date)
                    else:
                        res[x] = ''
                else:
                    res[x] = value[x] and float(value[x]) or 0.0

            if axis and isinstance(value[axis[0]], (tuple, list)):
                res['id'] = value[axis[0]][0]
            elif axis:
                res['id'] = value[axis[0]]
            else:
                res['id'] = False

            res['rec_id'] = rec_ids

            self.values.append(res)

        self.axis = axis
        self.axis_data = axis_data
        self.axis_group_field = axis_group
Beispiel #29
0
    def parse(self, prefix='', root=None, fields=None, values={}):

        views = []

        for node in root.childNodes:

            if node.nodeType not in (node.ELEMENT_NODE, node.TEXT_NODE):
                continue

            attrs = node_attributes(node)
            if self.noteditable:
                attrs['readonly'] = True
                attrs['force_readonly'] = True
                if 'attrs' in attrs and attrs['attrs'] and 'readonly' in attrs['attrs']:
                    dictattr = eval(attrs['attrs'])
                    if 'readonly' in dictattr:
                        del dictattr['readonly']
                    attrs['attrs'] = str(dictattr)
            attrs['prefix'] = prefix
            attrs['state'] = self.state

            if node.localName=='image':
                views.append(Image(**attrs))

            elif node.localName=='separator':
                views.append(Separator(**attrs))

            elif node.localName=='label':
                text = attrs.get('string', '')

                if not text:
                    for node in node.childNodes:
                        if node.nodeType == node.TEXT_NODE:
                            text += node.data
                        else:
                            text += node.toxml()

                attrs['string'] = text
                views.append(Label(**attrs))

            elif node.localName=='newline':
                views.append(NewLine(**attrs))

            elif node.localName=='button':
                attrs['editable'] = self.editable
                views.append(Button(model=self.model, id=self.id, **attrs))

            elif node.localName == 'form':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Frame(children=n, **attrs))

            elif node.localName == 'notebook':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                nb = Notebook(children=n, **attrs)
                self.nb_couter += 1
                nb._name = prefix.replace('/', '_') + '_notebook_%s'  % (self.nb_couter)
                views.append(nb)

            elif node.localName == 'page':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Page(children=n, **attrs))

            elif node.localName=='group':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Group(children=n, **attrs))

            elif node.localName == 'field':
                name = attrs['name']
                if name not in fields:
                    continue
                try:
                    fields[name]['link'] = attrs.get('link', '1')
                    if fields[name].get('no_write_access') and 'attrs' in attrs:
                        del attrs['attrs']
                    fields[name].update(attrs)
                except:
                    print "-"*30,"\n malformed tag for:", attrs
                    print "-"*30
                    raise

                kind = fields[name]['type']

                if not get_widget(kind):
                    continue

                if name in self.view_fields:
                    print "-"*30
                    print " malformed view for:", self.model
                    print " duplicate field:", name
                    print "-"*30
                    raise common.error(_('Application Error'), _('Invalid view, duplicate field: %s') % name)

                self.view_fields.append(name)

                field = self._make_field_widget(fields[name], values.get(name))
                views.append(field)

            elif node.localName=='hpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(HPaned(children=n, **attrs))

            elif node.localName=='vpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(VPaned(children=n, **attrs))

            elif node.localName in ('child1', 'child2'):
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                attrs['name'] = get_node_xpath(node)
                views.append(Dashbar(children=n, **attrs))

            elif node.localName=='action':
                wid = get_widget('action')(**attrs)
                views.append(wid)
                cherrypy.request._terp_dashboard = True

            else:
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                args = node_attributes(node)
                attrs['args'] = args
                attrs['tag_name'] = node.localName

                if node.nodeType == node.TEXT_NODE:
                    if not node.nodeValue.strip():
                        continue
                    attrs['value'] = node.nodeValue

                views.append(HtmlView(children=n, **attrs))


        return views
Beispiel #30
0
    def __init__(self, view, model, res_id=False, domain=[], context={}, action=None, fields=None):
        super(ViewTree, self).__init__(name='view_tree', action=action)

        self.model = view['model']
        self.domain2 = domain or []
        self.context = context or {}
        self.domain = []
        
        fields_info = dict(fields)

        self.field_parent = view.get("field_parent") or None

        if self.field_parent:
            self.domain = domain

        self.view = view
        self.view_id = view['view_id']

        proxy = rpc.RPCProxy(self.model)

        ctx = dict(self.context,
                   **rpc.session.context)
                
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))

        root = dom.childNodes[0]
        attrs = node_attributes(root)
        self.string = attrs.get('string', 'Unknown')
        self.toolbar = attrs.get('toolbar', False)
        # Set the button to be optional
        self.expand_button = attrs.get('expand_button', False)
        nolink = attrs.get('nolink', '0')
        ids = []
        id = res_id
        
        colors = {}
        for color_spec in attrs.get('colors', '').split(';'):
            if color_spec:
                colour, test = color_spec.split(':')
                colors[colour] = test
                
        if self.toolbar:
            ids = proxy.search(self.domain2, 0, 0, 0, ctx)
            self.toolbar = proxy.read(ids, ['name', 'icon'], ctx)

            if not id and ids:
                id = ids[0]

            if id:
                ids = proxy.read([id], [self.field_parent], ctx)[0][self.field_parent]
        elif not ids:
            ids = proxy.search(domain, 0, 0, 0, ctx)

        self.headers = []
        self.parse(root, fields)

        self.tree = treegrid.TreeGrid(name="tree_%d" % (id),
                                      model=self.model,
                                      headers=self.headers,
                                      url=url("/openerp/tree/data"),
                                      ids=ids,
                                      domain=self.domain,
                                      context=self.context,
                                      field_parent=self.field_parent,
                                      onselection="onSelection",
                                      fields_info=fields_info,
                                      colors=colors,
                                      nolink=nolink)
        self.id = id
        self.ids = ids

        toolbar = {}
        for item, value in view.get('toolbar', {}).items():
            if value: toolbar[item] = value
        if toolbar:
            self.sidebar = Sidebar(self.model, None, toolbar, context=self.context)

        # get the correct view title
        self.string = self.context.get('_terp_view_name', self.string) or self.string
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values = [row.copy() for row in data]

        myfields = []  # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'],
                                   {'context': self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))

            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-" * 30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-" * 30
                        raise common.error(
                            _('Application Error'),
                            _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            attrs['widget'] = 'one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(
                                name, False),
                                                   **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(
                                        expr,
                                        dict(row_value,
                                             active_id=rpc.session.active_id
                                             or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #32
0
    def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw):

        super(List, self).__init__(name=name, model=model, ids=ids)

        self.context = context or {}
        self.domain = domain or []
        custom_search_domain = getattr(cherrypy.request,
                                       'custom_search_domain', [])
        custom_filter_domain = getattr(cherrypy.request,
                                       'custom_filter_domain', [])

        if name.endswith('/'):
            self._name = name[:-1]
        if name != '_terp_list':
            self.source = self.name.replace('/', '/') or None

        self.sort_order = kw.get('sort_order', '')
        self.sort_key = kw.get('sort_key', '')
        #this Condition is for Dashboard to avoid new, edit, delete operation
        self.dashboard = 0

        self.selectable = kw.get('selectable', 0)
        self.editable = kw.get('editable', False)
        self.pageable = kw.get('pageable', True)
        self.view_mode = kw.get('view_mode', [])

        self.offset = kw.get('offset', 0)
        self.limit = kw.get('limit', 0)
        self.count = kw.get('count', 0)
        self.link = kw.get('nolinks')
        self.m2m = kw.get('m2m', 0)
        self.o2m = kw.get('o2m', 0)
        self.concurrency_info = None
        self.selector = None

        terp_params = getattr(cherrypy.request, 'terp_params', {})
        if terp_params:
            if terp_params.get('_terp_model'):
                if terp_params[
                        '_terp_model'] == 'board.board' and terp_params.view_type == 'form':
                    self.dashboard = 1
            if terp_params.get('_terp_source'):
                if (str(terp_params.source)
                        == self.source) or (terp_params.source == '_terp_list'
                                            and terp_params.sort_key):
                    self.sort_key = terp_params.sort_key
                    self.sort_order = terp_params.sort_order

        if self.selectable == 1:
            self.selector = 'radio'

        if self.selectable == 2:
            self.selector = 'checkbox'

        fields = view['fields']
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]

        attrs = node_attributes(root)
        self.string = attrs.get('string', '')

        search_param = copy.deepcopy(domain) or []
        if custom_search_domain:
            for elem in custom_search_domain:
                if elem not in self.domain:
                    search_param.append(elem)

            for elem in custom_filter_domain:
                if elem not in self.domain:
                    search_param.append(elem)

        try:
            self.limit = int(attrs.get('limit'))
        except:
            pass

        self.colors = {}
        for color_spec in attrs.get('colors', '').split(';'):
            if color_spec:
                colour, test = color_spec.split(':')
                self.colors[colour] = test

        proxy = rpc.RPCProxy(model)
        default_data = kw.get('default_data', [])
        search_text = terp_params.get('_terp_search_text', False)
        if not self.source:
            self.source = terp_params.get('_terp_source', None)
        if not default_data and not self.o2m and not self.m2m:
            if self.limit > 0:
                if self.sort_key:
                    ids = proxy.search(search_param, self.offset, self.limit,
                                       self.sort_key + ' ' + self.sort_order,
                                       context)
                else:
                    if search_text:
                        if self.source == '_terp_list':
                            ids = proxy.search(search_param, self.offset,
                                               self.limit, False, context)
                    else:
                        ids = proxy.search(search_param, self.offset,
                                           self.limit, False, context)
            else:
                if self.sort_key:
                    ids = proxy.search(search_param, 0, 0,
                                       self.sort_key + ' ' + self.sort_order,
                                       context)
                else:
                    ids = proxy.search(search_param, 0, 0, 0, context)
            if len(ids) < self.limit:
                if self.offset > 0:
                    self.count = len(ids) + self.offset
                else:
                    self.count = len(ids)
            else:
                self.count = proxy.search_count(search_param, context)

        if not default_data and self.m2m and not self.view_using_sum_attrs(
                root):
            # for many2many we limits 'ids' to be readed only when view is not
            # using sum, otherwise we need to get all 'ids' to compute sums correctly
            if ids and self.limit not in (0, -1):
                ids = self.ids[self.offset:self.offset + self.limit]

        self.data_dict = {}
        data = []

        if ids and not isinstance(ids, (list, tuple)):
            ids = [ids]

        if ids and len(ids) > 0:

            ctx = rpc.session.context.copy()
            ctx.update(context)

            try:
                data = proxy.read(ids, fields.keys() + ['__last_update'], ctx)
            except:
                pass

            ConcurrencyInfo.update(self.model, data)
            cherrypy.response.headers.pop('X-Concurrency-Info', None)
            self.concurrency_info = ConcurrencyInfo(self.model, ids)

            order_data = [(d['id'], d) for d in data]
            orderer = dict(zip(ids, count()))
            ordering = sorted(order_data,
                              key=lambda object: orderer[object[0]])
            data = [i[1] for i in ordering]

            for item in data:
                self.data_dict[item['id']] = item.copy()

            if not self.m2m:
                # update active 'ids' except for many2many which need to get
                # all known ids for update to work correctly
                self.ids = ids
        elif kw.get('default_data', []):
            data = kw['default_data']

        self.values = copy.deepcopy(data)
        self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse(
            root, fields, data)

        for k, v in self.field_total.items():
            if (len([test[0] for test in self.hiddens if test[0] == k])) <= 0:
                self.field_total[k][1] = self.do_sum(self.data, k)

        self.columns = len(self.headers)

        self.columns += (self.selectable or 0) and 1
        self.columns += (self.editable or 0) and 2
        self.columns += (self.buttons or 0) and 1

        if self.pageable:
            self.pager = Pager(ids=self.ids,
                               offset=self.offset,
                               limit=self.limit,
                               count=self.count)
            self.pager._name = self.name

        # when view is editable, make sure all fields are correctly prefixed
        # otherwise they may conflict with parent view fields
        if self.editable:
            for f, fa in self.headers + self.hiddens:
                if not isinstance(fa, int):
                    fa['prefix'] = '_terp_listfields' + (
                        (self.name != '_terp_list' or '') and '/' + self.name)

        if self.editable and context.get(
                'set_editable'
        ):  #Treeview editable by default or set_editable in context
            attrs['editable'] = "bottom"

        # make editors
        if self.editable and attrs.get('editable') in ('top', 'bottom'):

            for f, fa in self.headers:
                if not isinstance(fa, int):
                    fa['prefix'] = '_terp_listfields' + (
                        (self.name != '_terp_list' or '') and '/' + self.name)
                    fa['inline'] = True
                    if fa.get('type') == 'one2many':
                        self.edit_inline = False
                        self.editors = {}
                        break
                    Widget = get_widget(fa.get('type',
                                               'char')) or get_widget('char')
                    self.editors[f] = Widget(**fa)

            # generate hidden fields
            if self.editors:
                for f, fa in self.hiddens:
                    fa['prefix'] = '_terp_listfields' + (
                        (self.name != '_terp_list' or '') and '/' + self.name)
                    self.editors[f] = form.Hidden(**fa)

        # limit the data
        if self.pageable and len(self.data) > self.limit and self.limit != -1:
            self.data = self.data[self.offset:]
            self.data = self.data[:min(self.limit, len(self.data))]
Beispiel #33
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}

        myfields = []  # check for duplicate fields
        list_fields = []

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'],
                                   {'context': self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))

            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-" * 30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-" * 30
                        raise common.error(
                            _('Application Error'),
                            _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            attrs['widget'] = 'one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    list_fields.append((
                        name,
                        kind,
                        invisible,
                        fields[name],
                    ))

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #34
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []

        field_total = {}
        field_real_total = {}
        values  = [row.copy() for row in data]

        myfields = [] # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                if self.force_readonly:
                    continue
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'], {'context':self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))
            elif node.nodeName == 'separator':
                headers += [("separator", {'type': 'separator', 'string': '|', 'not_sortable': 1})]
            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-"*30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-"*30
                        raise common.error(_('Application Error'), _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget']=='one2many_list':
                            attrs['widget']='one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-"*30,"\n malformed tag for:", attrs
                        print "-"*30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = visval if isinstance(visval, bool) \
                            else eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]
                        
                    if 'real_sum' in attrs:
                        field_real_total[name] = [attrs['real_sum'], 0.0]

                    for i, row in enumerate(data):
                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr,
                                     dict(row_value, active_id=rpc.session.active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell
                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #35
0
    def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw):

        super(List, self).__init__(name=name, model=model, ids=ids)
        self.context = context or {}
        self.domain = domain or []
        custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', [])
        custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', [])

        if name.endswith('/'):
            self._name = name[:-1]
        if name != '_terp_list':
            self.source = self.name.replace('/', '/') or None
        
        self.sort_order = kw.get('sort_order', '')
        self.sort_key = kw.get('sort_key', '')
        #this Condition is for Dashboard to avoid new, edit, delete operation
        self.dashboard = 0
        self.noteditable = []
        self.notselectable = []
        self.selectable = kw.get('selectable', 0)
        self.editable = kw.get('editable', False)
        self.pageable = kw.get('pageable', True)
        self.view_mode = kw.get('view_mode', [])
        self.offset = kw.get('offset', 0)
        self.limit = None
        self.count = kw.get('count', 0)
        self.link = kw.get('nolinks')
        self.m2m = kw.get('m2m', 0)
        self.o2m = kw.get('o2m', 0)
        self.concurrency_info = None
        self.selector = None
        self.force_readonly = kw.get('force_readonly', False)

        terp_params = getattr(cherrypy.request, 'terp_params', {})
        if terp_params:
            if terp_params.get('_terp_model'):
                if terp_params['_terp_model'] == 'board.board' and terp_params.view_type == 'form':
                    self.dashboard = 1
            if terp_params.get('_terp_source'):
                if (str(terp_params.source) == self.source) or (terp_params.source == '_terp_list' and terp_params.sort_key):
                    self.sort_key = terp_params.sort_key
                    self.sort_order = terp_params.sort_order

        if self.selectable == 1:
            self.selector = 'radio'

        if self.selectable == 2:
            self.selector = 'checkbox'

        fields = view['fields']
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]

        attrs = node_attributes(root)
        
        # Get the hide status of some buttons - by default buttons are shown
        self.hide_new_button = False
        self.hide_delete_button = False
        self.hide_edit_button = False
        try:
            self.hide_new_button = expr_eval(attrs.get('hide_new_button', False), {'context': context})
            self.hide_delete_button = expr_eval(attrs.get('hide_delete_button', False), {'context': context})
            self.hide_edit_button = expr_eval(attrs.get('hide_edit_button', False), {'context': context})
        except:
            pass
        
        self.string = attrs.get('string','')

        search_param = copy.deepcopy(domain) or []
        if custom_search_domain:
            for elem in custom_search_domain:
                if elem not in self.domain:
                    search_param.append(elem)
                    
            for elem in custom_filter_domain:
                if elem not in self.domain:
                    search_param.append(elem)

        # -- Limits --
        # 1. use action limit or default global listview limit: 20
        # 2. apply tree view limit if defined in attrs: <tree limit='..'>...</tree>
        # 3. apply user limit if changed
        self.limit = getattr(cherrypy.request, 'action_limit', 20)
        if attrs.get('limit'):
            try:
                self.limit = int(attrs.get('limit'))
            except Exception:
                pass
        if kw.get('limit') is not None:
            self.limit = int(kw.get('limit'))

        self.colors = {}
        for color_spec in attrs.get('colors', '').split(';'):
            if color_spec:
                colour, test = color_spec.split(':')
                self.colors[colour] = test

        proxy = rpc.RPCProxy(model)
        
        default_data = kw.get('default_data', [])
        search_text = terp_params.get('_terp_search_text', False)
        approximation = False
        if not self.source:
            self.source = terp_params.get('_terp_source', None)
        if not default_data and not self.o2m and not self.m2m:
            if self.limit > 0:
                if self.sort_key:
                    ids = proxy.search(search_param, self.offset, self.limit, self.sort_key + ' ' +self.sort_order + ',id', context)
                else:
                    if search_text:
                        if self.source == '_terp_list':
                            ids = proxy.search(search_param, self.offset, self.limit, False, context)
                    else:
                        ids = proxy.search(search_param, self.offset, self.limit, False, context)
            else:
                ids = proxy.search(search_param, 0, 0, 0, context)
            if len(ids) < self.limit:
                if self.offset > 0:
                    self.count = len(ids) + self.offset
                else:
                    self.count = len(ids)
            else:
                self.count, approximation = proxy.approximate_search_count(search_param, context)

        if not default_data and self.m2m:
            # prefilter datas for m2m
            # XXX: make it explicit about how 'sum' are computed as this is going to change default behaviour
            if ids and self.limit not in (0, -1):
                ids = self.ids[self.offset:self.offset+self.limit]

        self.data_dict = {}
        data = []

        if ids and not isinstance(ids, list):
            ids = [ids]

        if ids and len(ids) > 0:

            ctx = rpc.session.context.copy()
            ctx.update(context)
            
            try:    
                data = proxy.read(ids, fields.keys() + ['__last_update'], ctx)
            except:
                pass

            ConcurrencyInfo.update(self.model, data)
            cherrypy.response.headers.pop('X-Concurrency-Info', None)
            self.concurrency_info = ConcurrencyInfo(self.model, ids)

            order_data = [(d['id'], d) for d in data]
            orderer = dict(zip(ids, count()))
            ordering = sorted(order_data, key=lambda object: orderer[object[0]])
            data = [i[1] for i in ordering]
            
            for item in data:
                self.data_dict[item['id']] = item.copy()

            if not self.m2m:
                self.ids = ids
        elif kw.get('default_data', []):
            data = kw['default_data']

        self.values = copy.deepcopy(data)
        self.headers, self.hiddens, self.data, self.field_total, self.field_real_total, self.buttons = self.parse(root, fields, data)
        
        for k, v in self.field_total.items():
            if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0:
                self.field_total[k][1] = self.do_sum(self.data, k)
                
        for k, v in self.field_real_total.items():
            if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0:
                self.field_real_total[k][1] = self.do_real_sum(self.data, k)

        self.columns = len(self.headers)

        self.columns += (self.selectable or 0) and 1
        self.columns += (self.editable or 0) and 2
        self.columns += (self.buttons or 0) and 1

        if self.pageable:
            self.pager = Pager(ids=self.ids, offset=self.offset,
                    limit=self.limit, count=self.count,
                    approximation=approximation)
            self.pager._name = self.name
           
        if self.editable and context.get('set_editable'):#Treeview editable by default or set_editable in context
            attrs['editable'] = "bottom"
       
        if self.selectable and attrs.get('notselectable'):
            for x in self.values:
                try:
                    if expr_eval(attrs.get('notselectable'), x):
                        self.notselectable.append(x['id'])
                except:
                    pass 

        self.resequencable = expr_eval(attrs.get('resequencable') or '1')
        # self.resequencable = True  # uncomment this if you want to disable this globally

        # make editors
        if self.editable and attrs.get('noteditable'):
            for x in self.values:
                try:
                    if expr_eval(attrs.get('noteditable'), x):
                        self.noteditable.append(x['id'])
                except:
                    pass

        if self.editable and attrs.get('editable') in ('top', 'bottom'):
            for f, fa in self.headers:
                if not isinstance(fa, int):
                    fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name)
                    fa['inline'] = True
                    if fa.get('type') == 'one2many':
                        self.edit_inline = False
                        self.editors = {}
                        break
                    Widget = get_widget(fa.get('type', 'char')) or get_widget('char')
                    self.editors[f] = Widget(**fa)

            # generate hidden fields
            if self.editors:
                for f, fa in self.hiddens:
                    fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name)
                    self.editors[f] = form.Hidden(**fa)

        # limit the data
        if self.pageable and len(self.data) > self.limit and self.limit != -1:
            self.data = self.data[self.offset:]
            self.data = self.data[:min(self.limit, len(self.data))]
Beispiel #36
0
    def __init__(self, model, ids, view, domain=[], context={}, options=None):

        super(ICalendar, self).__init__()

        self.info_fields = []
        self.fields = {}

        self.events = []

        self.colors = {}
        self.color_values = []

        self.calendar_fields = {}
        self.concurrency_info = None

        self.ids = ids
        self.model = model
        self.domain = domain or []
        self.context = context or {}
        self.options = options

        self.date_format = format.get_datetime_format("date")
        self.use_search = (options or None) and options.use_search

        try:
            dt = parse_datetime(options.selected_day)
            self.selected_day = Day(dt.year, dt.month, dt.day)
        except:
            pass

        view_id = view.get("view_id", False)

        dom = xml.dom.minidom.parseString(view["arch"].encode("utf-8"))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.string = attrs.get("string", "")
        self.date_start = attrs.get("date_start")
        self.date_delay = attrs.get("date_delay")
        self.date_stop = attrs.get("date_stop")
        self.color_field = attrs.get("color")
        self.day_length = int(attrs.get("day_length", 8))

        if options and options.mode:
            self.mode = options.mode
        else:
            self.mode = attrs.get("mode") or self.mode or "month"

        self.info_fields = self.parse(root, view["fields"])

        fields = view["fields"]
        fields = fields.keys() + [self.date_start, self.date_stop, self.date_delay, self.color_field, "state"]

        fields = list(set([x for x in fields if x]))

        self.fields = cache.fields_get(model, fields, rpc.get_session().context)

        if self.color_field and options and options.colors:
            self.colors = options.colors

        if self.color_field and options and options.color_values:
            self.color_values = options.color_values

        self.calendar_fields["date_start"] = dict(name=self.date_start, kind=self.fields[self.date_start]["type"])

        if self.date_delay:
            self.calendar_fields["date_delay"] = dict(name=self.date_delay, kind=self.fields[self.date_delay]["type"])

        if self.date_stop:
            self.calendar_fields["date_stop"] = dict(name=self.date_stop, kind=self.fields[self.date_stop]["type"])

        self.calendar_fields["day_length"] = self.day_length
    def parse(self, prefix='', root=None, fields=None, values={}):

        views = []

        for node in root.childNodes:

            if node.nodeType not in (node.ELEMENT_NODE, node.TEXT_NODE):
                continue

            attrs = node_attributes(node)
            attrs['prefix'] = prefix
            attrs['state'] = self.state

            if node.localName=='image':
                views.append(Image(**attrs))

            elif node.localName=='separator':
                views.append(Separator(**attrs))

            elif node.localName=='label':
                text = attrs.get('string', '')

                if not text:
                    for node in node.childNodes:
                        if node.nodeType == node.TEXT_NODE:
                            text += node.data
                        else:
                            text += node.toxml()

                attrs['string'] = text
                views.append(Label(**attrs))

            elif node.localName=='newline':
                views.append(NewLine(**attrs))

            elif node.localName=='button':
                attrs['editable'] = self.editable
                views.append(Button(model=self.model, id=self.id, **attrs))

            elif node.localName == 'form':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Frame(children=n, **attrs))

            elif node.localName == 'notebook':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                nb = Notebook(children=n, **attrs)
                self.nb_couter += 1
                nb._name = prefix.replace('/', '_') + '_notebook_%s'  % (self.nb_couter)
                views.append(nb)

            elif node.localName == 'page':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Page(children=n, **attrs))

            elif node.localName=='group':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Group(children=n, **attrs))

            elif node.localName == 'field':
                name = attrs['name']

                try:
                    fields[name]['link'] = attrs.get('link', '1')
                    fields[name].update(attrs)
                except:
                    print "-"*30,"\n malformed tag for:", attrs
                    print "-"*30
                    raise

                kind = fields[name]['type']

                if not get_widget(kind):
                    continue

                if name in self.view_fields:
                    print "-"*30
                    print " malformed view for:", self.model
                    print " duplicate field:", name
                    print "-"*30
                    raise common.error(_('Application Error'), _('Invalid view, duplicate field: %s') % name)

                self.view_fields.append(name)

                field = self._make_field_widget(fields[name], values.get(name))
                views.append(field)

            elif node.localName=='hpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(HPaned(children=n, **attrs))

            elif node.localName=='vpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(VPaned(children=n, **attrs))

            elif node.localName in ('child1', 'child2'):
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                attrs['name'] = get_node_xpath(node)
                views.append(Dashbar(children=n, **attrs))

            elif node.localName=='action':
                wid = get_widget('action')(**attrs)
                views.append(wid)
                cherrypy.request._terp_dashboard = True

            else:
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                args = node_attributes(node)
                attrs['args'] = args
                attrs['tag_name'] = node.localName

                if node.nodeType == node.TEXT_NODE:
                    if not node.nodeValue.strip():
                        continue
                    attrs['value'] = node.nodeValue

                views.append(HtmlView(children=n, **attrs))


        return views
Beispiel #38
0
    def parse(self, model=None, root=None, fields=None, values={}):

        views = []
        search_model = model

        filters_run = []
        for node in root.childNodes:
            if not node.nodeType == node.ELEMENT_NODE:
                continue

            if filters_run and node.localName != 'filter':
                views.append(FiltersGroup(children=filters_run))
                filters_run = []

            attrs = node_attributes(node)
            attrs.update(is_search=True, model=search_model)

            if 'nolabel' in attrs:
                attrs['nolabel'] = False

            if node.localName in ('form', 'tree', 'search', 'group'):
                if node.localName == 'group':
                    attrs['group_by_ctx'] = values.get('group_by_ctx')
                    attrs['expand'] = expr_eval(attrs.get('expand', False),
                                                {'context': self.context})
                    Element = Group
                else:
                    Element = Frame

                views.append(
                    Element(children=self.parse(model=search_model,
                                                root=node,
                                                fields=fields,
                                                values=values),
                            **attrs))

            elif node.localName == 'newline':
                views.append(NewLine(**attrs))

            elif node.localName == 'filter':
                attrs.update(model=search_model,
                             default_domain=self.domain,
                             screen_context=self.context)
                if values and values.get('group_by_ctx'):
                    attrs['group_by_ctx'] = values['group_by_ctx']
                elif self.groupby:
                    attrs['group_by_ctx'] = self.groupby

                if values and values.get('filter_status'):
                    attrs['filter_status'] = values['filter_status']

                v = Filter(**attrs)
                if v.groupcontext and v.groupcontext not in self.groupby:
                    self.groupby.append(v.groupcontext)
                self.listof_domain.extend(i for i in v.global_domain
                                          if not i in self.listof_domain)
                filters_run.append(v)

            elif node.localName == 'field':
                val = attrs.get(
                    'select', False) or fields[str(attrs['name'])].get(
                        'select', False) or self.view_type == 'search'
                if val:
                    name = attrs['name']
                    if name in self.fields_type:
                        continue

                    # in search view fields should be writable
                    attrs.update(readonly=False,
                                 required=False,
                                 translate=False,
                                 disabled=False,
                                 visible=True,
                                 invisible=False,
                                 editable=True,
                                 attrs=None)

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            fields[name]['widget'] = 'one2many'

                        fields[name]['type2'] = fields[name]['type']
                        fields[name]['type'] = attrs['widget']

                    kind = fields[name]['type']

                    if kind not in WIDGETS:
                        continue

                    if kind == 'many2one':
                        attrs['relation'] = fields[name]['relation']
                        attrs['type'] = fields[name]['type']
                        if not attrs.get('string'):
                            attrs['string'] = fields[name]['string']

                    self.fields_type[name] = kind

                    field = WIDGETS[kind](**fields[name])
                    field.onchange = None
                    field.callback = None

                    if kind == 'boolean':
                        # '0' in string because 0 is considering as No Value, and we need 0 as some value.
                        field.options = [[1, _('Yes')], ['0', _('No')]]
                        field.validator.if_empty = ''

                    default_search = None
                    if name:
                        default_search = get_search_default(
                            fields[name], self.context, self.domain)
                        defval = default_search
                        if defval:
                            model = fields[name].get('relation')
                            type2 = fields[name].get('type2')

                            if kind == 'many2one' and model:
                                try:
                                    value = rpc.name_get(
                                        model, default_search, self.context)
                                except Exception, e:
                                    value = defval
                                defval = value or ''

                            if attrs.get('filter_domain'):
                                domain = expr_eval(attrs['filter_domain'],
                                                   {'self': defval})
                            else:
                                if field.kind == 'selection':
                                    if type2 == 'many2one':
                                        m2nval = defval
                                        try:
                                            m2nval = int(defval)
                                        except:
                                            # you see, since defval can basically be anything, including a totally
                                            # illogic value, my only possibility is to do return another illogic value,
                                            # so it won't crash too much
                                            pass
                                        domain = [(name, '=', m2nval)]
                                    else:
                                        domain = [(name, '=', defval)]

                                elif field.kind in ('date', 'datetime'):
                                    domain = [(name, '>=', defval)]

                                elif field.kind == 'boolean':
                                    domain = [(name, '=', defval)]

                                else:
                                    domain = [(name, fields[name].get(
                                        'comparator', 'ilike'), defval)]

                            field.set_value(defval)
                            self.listof_domain += [
                                i for i in domain
                                if not i in self.listof_domain
                            ]
                            self.context.update(
                                expr_eval(attrs.get('context', "{}"),
                                          {'self': default_search}))

                    if (not default_search) and name in values and isinstance(
                            field, TinyInputWidget):
                        field.set_value(values[name])

                    views.append(field)
                    for n in node.childNodes:
                        if n.localName == 'filter':
                            attrs_child = dict(node_attributes(n),
                                               default_domain=self.domain,
                                               screen_context=self.context)
                            if 'string' in attrs_child:
                                del attrs_child['string']
                            if values and values.get('group_by_ctx'):
                                attrs['group_by_ctx'] = values['group_by_ctx']

                            filter_field = Filter(**attrs_child)
                            filter_field.onchange = None
                            filter_field.callback = None

                            if filter_field.groupcontext and filter_field.groupcontext not in self.groupby:
                                self.groupby.append(filter_field.groupcontext)
                            self.listof_domain.extend(
                                i for i in filter_field.global_domain
                                if i not in self.listof_domain)
                            field.filters.append(filter_field)
Beispiel #39
0
    def parse(self, model=None, root=None, fields=None, values={}):

        views = []
        search_model = model

        filters_run = []
        for node in root.childNodes:
            if not node.nodeType==node.ELEMENT_NODE:
                continue

            if filters_run and node.localName != 'filter':
                views.append(FiltersGroup(children=filters_run))
                filters_run = []

            attrs = node_attributes(node)
            attrs.update(is_search=True,
                         model=search_model)

            if 'nolabel' in attrs:
                attrs['nolabel'] = False

            if node.localName in ('form', 'tree', 'search', 'group'):
                if node.localName == 'group':
                    attrs['group_by_ctx'] = values.get('group_by_ctx')
                    attrs['expand'] = expr_eval(attrs.get('expand',False),{'context':self.context})
                    Element = Group
                else:
                    Element = Frame

                views.append(Element(children=
                                     self.parse(model=search_model, root=node,
                                                fields=fields, values=values),
                                     **attrs))

            elif node.localName=='newline':
                views.append(NewLine(**attrs))

            elif node.localName=='filter':
                attrs.update(
                    model=search_model,
                    default_domain=self.domain,
                    screen_context=self.context)
                if values and values.get('group_by_ctx'):
                    attrs['group_by_ctx'] = values['group_by_ctx']
                elif self.groupby:
                    attrs['group_by_ctx'] = self.groupby

                v = Filter(**attrs)
                if v.groupcontext and v.groupcontext not in self.groupby:
                    self.groupby.append(v.groupcontext)
                self.listof_domain.extend(i for i in v.global_domain if not i in self.listof_domain)
                filters_run.append(v)

            elif node.localName == 'field':
                val  = attrs.get('select', False) or fields[str(attrs['name'])].get('select', False) or self.view_type == 'search'
                if val:
                    name = attrs['name']
                    if name in self.fields_type:
                        continue

                    # in search view fields should be writable
                    attrs.update(readonly=False,
                                 required=False,
                                 translate=False,
                                 disabled=False,
                                 visible=True,
                                 invisible=False,
                                 editable=True,
                                 attrs=None)

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-"*30,"\n malformed tag for:", attrs
                        print "-"*30
                        raise

                    if attrs.get('widget'):
                        if attrs['widget'] == 'one2many_list':
                            fields[name]['widget'] = 'one2many'

                        fields[name]['type2'] = fields[name]['type']
                        fields[name]['type'] = attrs['widget']

                    kind = fields[name]['type']

                    if kind not in WIDGETS:
                        continue

                    if kind == 'many2one':
                        attrs['relation'] = fields[name]['relation']
                        attrs['type'] = fields[name]['type']
                        if not attrs.get('string'):
                            attrs['string'] = fields[name]['string']

                    self.fields_type[name] = kind

                    field = WIDGETS[kind](**fields[name])
                    field.onchange = None
                    field.callback = None

                    if kind == 'boolean':
                        # '0' in string because 0 is considering as No Value, and we need 0 as some value.
                        field.options = [[1,_('Yes')],['0',_('No')]]
                        field.validator.if_empty = ''

                    default_search = None
                    if name:
                        default_search = get_search_default(fields[name], self.context, self.domain)
                        defval = default_search
                        if defval:
                            model = fields[name].get('relation')
                            type2 = fields[name].get('type2')

                            if kind == 'many2one' and model:
                                try:
                                    value = rpc.name_get(model, default_search, self.context)
                                except Exception,e:
                                    value = defval
                                defval = value or ''

                            if attrs.get('filter_domain'):
                                domain = expr_eval(attrs['filter_domain'], {'self': defval})
                            else:
                                if field.kind == 'selection':
                                    if type2 == 'many2one':
                                        m2nval = defval
                                        try:
                                            m2nval = int(defval)
                                        except:
                                            # you see, since defval can basically be anything, including a totally
                                            # illogic value, my only possibility is to do return another illogic value,
                                            # so it won't crash too much
                                            pass
                                        domain = [(name, '=', m2nval)]
                                    else:
                                        domain = [(name, '=', defval)]

                                elif field.kind in ('date','datetime'):
                                    domain = [(name, '>=', defval)]
                                    
                                elif field.kind == 'boolean':
                                    domain = [(name, '=', defval)]
                                               
                                else:
                                    domain = [(name,fields[name].get('comparator','ilike'), defval)]

                            field.set_value(defval)
                            self.listof_domain += [i for i in domain if not i in self.listof_domain]
                            self.context.update(expr_eval(attrs.get('context',"{}"), {'self': default_search}))

                    if (not default_search) and name in values and isinstance(field, TinyInputWidget):
                        field.set_value(values[name])

                    views.append(field)
                    for n in node.childNodes:
                        if n.localName=='filter':
                            attrs_child = dict(
                                node_attributes(n),
                                default_domain=self.domain,
                                screen_context=self.context)
                            if 'string' in attrs_child: del attrs_child['string']
                            if values and values.get('group_by_ctx'):
                                attrs['group_by_ctx'] = values['group_by_ctx']

                            filter_field = Filter(**attrs_child)
                            filter_field.onchange = None
                            filter_field.callback = None

                            if filter_field.groupcontext and filter_field.groupcontext not in self.groupby:
                                self.groupby.append(filter_field.groupcontext)
                            self.listof_domain.extend(i for i in filter_field.global_domain
                                                        if i not in self.listof_domain)
                            field.filters.append(filter_field)
Beispiel #40
0
    def parse(self, prefix='', root=None, fields=None, values={}):

        views = []

        for node in root.childNodes:

            if node.nodeType not in (node.ELEMENT_NODE, node.TEXT_NODE):
                continue

            attrs = node_attributes(node)
            attrs['prefix'] = prefix
            attrs['state'] = self.state

            if node.localName=='image':
                views.append(Image(**attrs))

            elif node.localName=='separator':
                views.append(Separator(**attrs))

            elif node.localName=='label':
                text = attrs.get('string', '')

                if not text:
                    for node in node.childNodes:
                        if node.nodeType == node.TEXT_NODE:
                            text += node.data
                        else:
                            text += node.toxml()

                attrs['string'] = text
                views.append(Label(**attrs))

            elif node.localName=='newline':
                views.append(NewLine(**attrs))

            elif node.localName=='button':
                attrs['editable'] = self.editable
                views.append(Button(model=self.model, id=self.id, **attrs))

            elif node.localName == 'form':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Frame(children=n, **attrs))

            elif node.localName == 'notebook':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                nb = Notebook(children=n, **attrs)
                self.nb_couter += 1
                nb._name = prefix.replace('/', '_') + '_notebook_%s'  % (self.nb_couter)
                views.append(nb)

            elif node.localName == 'page':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Page(children=n, **attrs))

            elif node.localName=='group':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(Group(children=n, **attrs))

            elif node.localName == 'field':
                name = attrs['name']

                try:
                    fields[name]['link'] = attrs.get('link', '1')
                    fields[name].update(attrs)
                except:
                    parse_logger.debug("Malformed tag for field %s, with %s",
                                       name, attrs)
                    raise

                kind = fields[name]['type']

                if not get_widget(kind):
                    continue

                if name in self.view_fields:
                    raise common.error(
                        _('Application Error'),
                        _("Invalid view for model '%(model)s', duplicate field: %(field)s",
                          model=self.model, name=name))

                self.view_fields.append(name)

                field = self._make_field_widget(fields[name], values.get(name))
                views.append(field)

            elif node.localName=='hpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(HPaned(children=n, **attrs))

            elif node.localName=='vpaned':
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                views.append(VPaned(children=n, **attrs))

            elif node.localName in ('child1', 'child2'):
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                attrs['name'] = get_node_xpath(node)
                views.append(Dashbar(children=n, **attrs))

            elif node.localName=='action':
                wid = get_widget('action')(**attrs)
                views.append(wid)
                cherrypy.request._terp_dashboard = True

            else:
                n = self.parse(prefix=prefix, root=node, fields=fields, values=values)
                args = node_attributes(node)
                attrs['args'] = args
                attrs['tag_name'] = node.localName

                if node.nodeType == node.TEXT_NODE:
                    if not node.nodeValue.strip():
                        continue
                    attrs['value'] = node.nodeValue

                views.append(HtmlView(children=n, **attrs))


        return views
Beispiel #41
0
    def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw):

        super(List, self).__init__(name=name, model=model, ids=ids)

        self.context = context or {}
        self.domain = domain or []
        custom_search_domain = getattr(cherrypy.request, "custom_search_domain", [])
        custom_filter_domain = getattr(cherrypy.request, "custom_filter_domain", [])

        if name.endswith("/"):
            self._name = name[:-1]
        if name != "_terp_list":
            self.source = self.name.replace("/", "/") or None

        self.sort_order = ""
        self.sort_key = ""
        # this Condition is for Dashboard to avoid new, edit, delete operation
        self.dashboard = 0

        self.selectable = kw.get("selectable", 0)
        self.editable = kw.get("editable", False)
        self.pageable = kw.get("pageable", True)
        self.view_mode = kw.get("view_mode", [])

        self.offset = kw.get("offset", 0)
        self.limit = kw.get("limit", 0)
        self.count = kw.get("count", 0)
        self.link = kw.get("nolinks")
        self.m2m = kw.get("m2m", 0)
        self.o2m = kw.get("o2m", 0)
        self.concurrency_info = None
        self.selector = None

        terp_params = getattr(cherrypy.request, "terp_params", {})
        if terp_params:
            if terp_params.get("_terp_model"):
                if terp_params["_terp_model"] == "board.board" and terp_params.view_type == "form":
                    self.dashboard = 1
            if terp_params.get("_terp_source"):
                if (str(terp_params.source) == self.source) or (
                    terp_params.source == "_terp_list" and terp_params.sort_key
                ):
                    self.sort_key = terp_params.sort_key
                    self.sort_order = terp_params.sort_order

        if self.selectable == 1:
            self.selector = "radio"

        if self.selectable == 2:
            self.selector = "checkbox"

        fields = view["fields"]
        dom = xml.dom.minidom.parseString(view["arch"].encode("utf-8"))
        root = dom.childNodes[0]

        attrs = node_attributes(root)
        self.string = attrs.get("string", "")

        search_param = copy.deepcopy(domain) or []
        if custom_search_domain:
            for elem in custom_search_domain:
                if elem not in self.domain:
                    search_param.append(elem)

            for elem in custom_filter_domain:
                if elem not in self.domain:
                    search_param.append(elem)

        try:
            self.limit = int(attrs.get("limit"))
        except:
            pass

        self.colors = {}
        for color_spec in attrs.get("colors", "").split(";"):
            if color_spec:
                colour, test = color_spec.split(":")
                self.colors[colour] = test

        proxy = rpc.RPCProxy(model)
        default_data = kw.get("default_data", [])
        search_text = terp_params.get("_terp_search_text", False)
        if not self.source:
            self.source = terp_params.get("_terp_source", None)
        if not default_data and not self.o2m and not self.m2m:
            if self.limit > 0:
                if self.sort_key:
                    ids = proxy.search(
                        search_param, self.offset, self.limit, self.sort_key + " " + self.sort_order, context
                    )
                else:
                    if search_text:
                        if self.source == "_terp_list":
                            ids = proxy.search(search_param, self.offset, self.limit, False, context)
                    else:
                        ids = proxy.search(search_param, self.offset, self.limit, False, context)
            else:
                ids = proxy.search(search_param, 0, 0, 0, context)
            if len(ids) < self.limit:
                if self.offset > 0:
                    self.count = len(ids) + self.offset
                else:
                    self.count = len(ids)
            else:
                self.count = proxy.search_count(search_param, context)

        self.data_dict = {}
        data = []

        if ids and not isinstance(ids, list):
            ids = [ids]

        if ids and len(ids) > 0:

            ctx = rpc.session.context.copy()
            ctx.update(context)

            try:
                data = proxy.read(ids, fields.keys() + ["__last_update"], ctx)
            except:
                pass

            ConcurrencyInfo.update(self.model, data)
            cherrypy.response.headers.pop("X-Concurrency-Info", None)
            self.concurrency_info = ConcurrencyInfo(self.model, ids)

            order_data = [(d["id"], d) for d in data]
            orderer = dict(zip(ids, count()))
            ordering = sorted(order_data, key=lambda object: orderer[object[0]])
            data = [i[1] for i in ordering]

            for item in data:
                self.data_dict[item["id"]] = item.copy()

            self.ids = ids
        elif kw.get("default_data", []):
            data = kw["default_data"]

        self.values = copy.deepcopy(data)
        self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse(root, fields, data)

        for k, v in self.field_total.items():
            if (len([test[0] for test in self.hiddens if test[0] == k])) <= 0:
                self.field_total[k][1] = self.do_sum(self.data, k)

        self.columns = len(self.headers)

        self.columns += (self.selectable or 0) and 1
        self.columns += (self.editable or 0) and 2
        self.columns += (self.buttons or 0) and 1

        if self.pageable:
            self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count)
            self.pager._name = self.name

        if self.editable and context.get("set_editable"):  # Treeview editable by default or set_editable in context
            attrs["editable"] = "bottom"

        # make editors
        if self.editable and attrs.get("editable") in ("top", "bottom"):

            for f, fa in self.headers:
                if not isinstance(fa, int):
                    fa["prefix"] = "_terp_listfields" + ((self.name != "_terp_list" or "") and "/" + self.name)
                    fa["inline"] = True
                    if fa.get("type") == "one2many":
                        self.edit_inline = False
                        self.editors = {}
                        break
                    Widget = get_widget(fa.get("type", "char")) or get_widget("char")
                    self.editors[f] = Widget(**fa)

            # generate hidden fields
            if self.editors:
                for f, fa in self.hiddens:
                    fa["prefix"] = "_terp_listfields" + ((self.name != "_terp_list" or "") and "/" + self.name)
                    self.editors[f] = form.Hidden(**fa)

        # limit the data
        if self.pageable and len(self.data) > self.limit and self.limit != -1:
            self.data = self.data[self.offset :]
            self.data = self.data[: min(self.limit, len(self.data))]
Beispiel #42
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}

        myfields = [] # check for duplicate fields
        list_fields = []

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'], {'context':self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))
                
            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        print "-"*30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-"*30
                        raise common.error(_('Application Error'), _('Invalid view, duplicate field: %s') % name)

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget']=='one2many_list':
                            attrs['widget']='one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-"*30,"\n malformed tag for:", attrs
                        print "-"*30
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context='listgrid.List.parse')
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    list_fields.append((name, kind, invisible, fields[name],))

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #43
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values = [row.copy() for row in data]

        myfields = []  # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == "button":
                attrs = node_attributes(node)
                if attrs.get("invisible", False):
                    visible = eval(attrs["invisible"], {"context": self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))

            elif node.nodeName == "field":
                attrs = node_attributes(node)

                if "name" in attrs:

                    name = attrs["name"]

                    if name in myfields:
                        print "-" * 30
                        print " malformed view for:", self.model
                        print " duplicate field:", name
                        print "-" * 30
                        raise common.error(_("Application Error"), _("Invalid view, duplicate field: %s") % name)

                    myfields.append(name)

                    if attrs.get("widget"):
                        if attrs["widget"] == "one2many_list":
                            attrs["widget"] = "one2many"
                        attrs["type"] = attrs["widget"]

                    try:
                        fields[name].update(attrs)
                    except:
                        print "-" * 30, "\n malformed tag for:", attrs
                        print "-" * 30
                        raise

                    kind = fields[name]["type"]

                    if kind not in CELLTYPES:
                        kind = "char"

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get("invisible", "False")
                        invisible = eval(visval, {"context": self.context})
                    except NameError, e:
                        cherrypy.log.error(e, context="listgrid.List.parse")
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if "sum" in attrs:
                        field_total[name] = [attrs["sum"], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr, dict(row_value, active_id=rpc.session.active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #44
0
    def parse(self, root, fields, data=[]):
        """Parse the given node to generate valid list headers.

        @param root: the root node of the view
        @param fields: the fields

        @return: an instance of List
        """

        headers = []
        hiddens = []
        buttons = []
        field_total = {}
        values  = [row.copy() for row in data]

        myfields = [] # check for duplicate fields

        for node in root.childNodes:

            if node.nodeName == 'button':
                attrs = node_attributes(node)
                if attrs.get('invisible', False):
                    visible = eval(attrs['invisible'], {'context':self.context})
                    if visible:
                        continue
                buttons += [Button(**attrs)]
                headers.append(("button", len(buttons)))
                
            elif node.nodeName == 'field':
                attrs = node_attributes(node)

                if 'name' in attrs:

                    name = attrs['name']

                    if name in myfields:
                        raise common.error(
                            _('Application Error'),
                            _("Invalid view for model '%(model)s', duplicate field: %(field)s",
                              model=self.model, name=name))

                    myfields.append(name)

                    if attrs.get('widget'):
                        if attrs['widget']=='one2many_list':
                            attrs['widget']='one2many'
                        attrs['type'] = attrs['widget']

                    try:
                        fields[name].update(attrs)
                    except:
                        parse_logger.debug(
                            "Malformed tag for field %s, with %s",
                            name, attrs)
                        raise

                    kind = fields[name]['type']

                    if kind not in CELLTYPES:
                        kind = 'char'

                    fields[name].update(attrs)

                    try:
                        visval = fields[name].get('invisible', 'False')
                        invisible = eval(visval, {'context': self.context})
                    except NameError, e:
                        parse_logger.info(e)
                        invisible = False

                    if invisible:
                        hiddens += [(name, fields[name])]

                    if 'sum' in attrs:
                        field_total[name] = [attrs['sum'], 0.0]

                    for i, row in enumerate(data):

                        row_value = values[i]
                        if invisible:
                            cell = Hidden(**fields[name])
                            cell.set_value(row_value.get(name, False))
                        else:
                            cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name])

                        for color, expr in self.colors.items():
                            try:
                                if expr_eval(expr,
                                     dict(row_value, active_id=rpc.get_session().active_id or False)):
                                    cell.color = color
                                    break
                            except:
                                pass

                        row[name] = cell

                    if invisible:
                        continue

                    headers += [(name, fields[name])]
Beispiel #45
0
    def __init__(self, model, ids, view, domain=[], context={}, options=None):

        super(ICalendar, self).__init__()

        self.info_fields = []
        self.fields = {}

        self.events = []

        self.colors = {}
        self.color_values = []

        self.calendar_fields = {}
        self.concurrency_info = None

        self.ids = ids
        self.model = model
        self.domain = domain or []
        self.context = context or {}
        self.options = options

        self.date_format = format.get_datetime_format('date')
        self.use_search = (options or None) and options.use_search

        try:
            dt = parse_datetime(options.selected_day)
            self.selected_day = Day(dt.year, dt.month, dt.day)
        except:
            pass

        view_id = view.get('view_id', False)

        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]
        attrs = node_attributes(root)

        self.string = attrs.get('string', '')
        self.date_start = attrs.get('date_start')
        self.date_delay = attrs.get('date_delay')
        self.date_stop = attrs.get('date_stop')
        self.color_field = attrs.get('color')
        self.day_length = int(attrs.get('day_length', 24))

        if options and options.mode:
            self.mode = options.mode
        else:
            self.mode = attrs.get('mode') or self.mode or 'month'

        self.info_fields = self.parse(root, view['fields'])

        fields = view['fields']
        fields = fields.keys() + [
            self.date_start, self.date_stop, self.date_delay, self.color_field,
            'state'
        ]

        fields = list(set([x for x in fields if x]))

        self.fields = cache.fields_get(model, fields, rpc.session.context)

        if self.color_field and options and options.colors:
            self.colors = options.colors

        if self.color_field and options and options.color_values:
            self.color_values = options.color_values

        self.calendar_fields['date_start'] = dict(
            name=self.date_start, kind=self.fields[self.date_start]['type'])

        if self.date_delay:
            self.calendar_fields['date_delay'] = dict(
                name=self.date_delay,
                kind=self.fields[self.date_delay]['type'])

        if self.date_stop:
            self.calendar_fields['date_stop'] = dict(
                name=self.date_stop, kind=self.fields[self.date_stop]['type'])

        self.calendar_fields['day_length'] = self.day_length
Beispiel #46
0
    def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw):

        super(List, self).__init__(name=name, model=model, ids=ids)
        
        self.context = context or {}
        self.domain = domain or []
        custom_search_domain = getattr(cherrypy.request, 'custom_search_domain', [])
        custom_filter_domain = getattr(cherrypy.request, 'custom_filter_domain', [])

        if name.endswith('/'):
            self._name = name[:-1]
        if name != '_terp_list':
            self.source = self.name.replace('/', '/') or None
        
        self.sort_order = ''
        self.sort_key = ''
        #this Condition is for Dashboard to avoid new, edit, delete operation
        self.dashboard = 0
        
        self.selectable = kw.get('selectable', 0)
        self.editable = kw.get('editable', False)
        self.pageable = kw.get('pageable', True)
        self.view_mode = kw.get('view_mode', [])
        
        self.offset = kw.get('offset', 0)
        self.limit = kw.get('limit', 0)
        self.count = kw.get('count', 0)
        self.link = kw.get('nolinks')
        self.m2m = kw.get('m2m', 0)
        self.o2m = kw.get('o2m', 0)
        self.concurrency_info = None
        self.selector = None

        terp_params = getattr(cherrypy.request, 'terp_params', {})
        if terp_params:
            if terp_params.get('_terp_model'):
                if terp_params['_terp_model'] == 'board.board' and terp_params.view_type == 'form':
                    self.dashboard = 1
            if terp_params.get('_terp_source'):
                if (str(terp_params.source) == self.source) or (terp_params.source == '_terp_list' and terp_params.sort_key):
                    self.sort_key = terp_params.sort_key
                    self.sort_order = terp_params.sort_order
        
        if self.selectable == 1:
            self.selector = 'radio'

        if self.selectable == 2:
            self.selector = 'checkbox'

        fields = view['fields']
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))
        root = dom.childNodes[0]

        attrs = node_attributes(root)
        self.string = attrs.get('string','')

        search_param = copy.deepcopy(domain) or []
        if custom_search_domain:
            for elem in custom_search_domain:
                if elem not in self.domain:
                    search_param.append(elem)
                    
            for elem in custom_filter_domain:
                if elem not in self.domain:
                    search_param.append(elem)

        try:
            self.limit = int(attrs.get('limit'))
        except:
            pass

        self.colors = {}
        for color_spec in attrs.get('colors', '').split(';'):
            if color_spec:
                colour, test = color_spec.split(':')
                self.colors[colour] = test

        proxy = rpc.RPCProxy(model)
        
        default_data = kw.get('default_data', [])
        search_text = terp_params.get('_terp_search_text', False)
        if not self.source:
            self.source = terp_params.get('_terp_source', None)
        if not default_data and not self.o2m and not self.m2m:
            if self.limit > 0:
                if self.sort_key:
                    ids = proxy.search(search_param, self.offset, self.limit, self.sort_key + ' ' +self.sort_order, context)
                else:
                    if search_text:
                        if self.source == '_terp_list':
                            ids = proxy.search(search_param, self.offset, self.limit, False, context)
                    else:
                        ids = proxy.search(search_param, self.offset, self.limit, False, context)
            else:
                ids = proxy.search(search_param, 0, 0, 0, context)
            if len(ids) < self.limit:
                if self.offset > 0:
                    self.count = len(ids) + self.offset
                else:
                    self.count = len(ids)
            else:
                self.count = proxy.search_count(search_param, context)

        self.data_dict = {}
        data = []

        if ids and not isinstance(ids, list):
            ids = [ids]

        if ids and len(ids) > 0:

            ctx = rpc.get_session().context.copy()
            ctx.update(context)
            
            try:    
                data = proxy.read(ids, fields.keys() + ['__last_update'], ctx)
            except:
                pass

            ConcurrencyInfo.update(self.model, data)
            cherrypy.response.headers.pop('X-Concurrency-Info', None)
            self.concurrency_info = ConcurrencyInfo(self.model, ids)

            order_data = [(d['id'], d) for d in data]
            orderer = dict(zip(ids, count()))
            ordering = sorted(order_data, key=lambda object: orderer[object[0]])
            data = [i[1] for i in ordering]
            
            for item in data:
                self.data_dict[item['id']] = item.copy()

            self.ids = ids
        elif kw.get('default_data', []):
            data = kw['default_data']

        self.values = copy.deepcopy(data)
        self.headers, self.hiddens, self.data, self.field_total, self.buttons = self.parse(root, fields, data)

        for k, v in self.field_total.items():
            if(len([test[0] for test in self.hiddens if test[0] == k])) <= 0:
                self.field_total[k][1] = self.do_sum(self.data, k)

        self.columns = len(self.headers)

        self.columns += (self.selectable or 0) and 1
        self.columns += (self.editable or 0) and 2
        self.columns += (self.buttons or 0) and 1

        if self.pageable:
            self.pager = Pager(ids=self.ids, offset=self.offset, limit=self.limit, count=self.count)
            self.pager._name = self.name
           
        if self.editable and context.get('set_editable'):#Treeview editable by default or set_editable in context
            attrs['editable'] = "bottom"
        
        # make editors
        if self.editable and attrs.get('editable') in ('top', 'bottom'):

            for f, fa in self.headers:
                if not isinstance(fa, int):
                    fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name)
                    fa['inline'] = True
                    if fa.get('type') == 'one2many':
                        self.edit_inline = False
                        self.editors = {}
                        break
                    Widget = get_widget(fa.get('type', 'char')) or get_widget('char')
                    self.editors[f] = Widget(**fa)

            # generate hidden fields
            if self.editors:
                for f, fa in self.hiddens:
                    fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name)
                    self.editors[f] = form.Hidden(**fa)

        # limit the data
        if self.pageable and len(self.data) > self.limit and self.limit != -1:
            self.data = self.data[self.offset:]
            self.data = self.data[:min(self.limit, len(self.data))]
Beispiel #47
0
    def __init__(self, view, model, res_id=False, domain=[], context={}, action=None, fields=None):
        super(ViewTree, self).__init__(name='view_tree', action=action)

        self.model = view['model']
        self.domain2 = domain or []
        self.context = context or {}
        self.domain = []
        
        fields_info = dict(fields)

        self.field_parent = view.get("field_parent") or None

        if self.field_parent:
            self.domain = domain

        self.view = view
        self.view_id = view['view_id']

        proxy = rpc.RPCProxy(self.model)

        ctx = dict(self.context,
                   **rpc.get_session().context)
                
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))

        root = dom.childNodes[0]
        attrs = node_attributes(root)
        self.string = attrs.get('string', 'Unknown')
        self.toolbar = attrs.get('toolbar', False)

        ids = []
        id = res_id

        if self.toolbar:
            ids = proxy.search(self.domain2, 0, 0, 0, ctx)
            self.toolbar = proxy.read(ids, ['name', 'icon'], ctx)

            if not id and ids:
                id = ids[0]

            if id:
                ids = proxy.read([id], [self.field_parent])[0][self.field_parent]
        elif not ids:
            ids = proxy.search(domain, 0, 0, 0, ctx)

        self.headers = []
        self.parse(root, fields)

        self.tree = treegrid.TreeGrid(name="tree_%d" % (id),
                                      model=self.model,
                                      headers=self.headers,
                                      url=url("/openerp/tree/data"),
                                      ids=ids,
                                      domain=self.domain,
                                      context=self.context,
                                      field_parent=self.field_parent,
                                      onselection="onSelection",
                                      fields_info=fields_info)
        self.id = id
        self.ids = ids
        self.view_type = view.get('type')

        toolbar = {}
        for item, value in view.get('toolbar', {}).items():
            if value: 
                toolbar[item] = value

        if toolbar:
            self.sidebar = Sidebar(self.model, None, toolbar, self.id, self.view_type, context=self.context)
        else:
            if attrs.get('toolbar') and attrs['toolbar']:
                self.sidebar = Sidebar(self.model, None, None, self.id, self.view_type, context=self.context)
        
        # get the correct view title
        self.string = self.context.get('_terp_view_name', self.string) or self.string
Beispiel #48
0
    def __init__(self, view, model, res_id=False, domain=[], context={}, action=None, fields=None):
        super(ViewTree, self).__init__(name='view_tree', action=action)

        self.model = view['model']
        self.domain2 = domain or []
        self.context = context or {}
        self.domain = []
        
        fields_info = dict(fields)

        self.field_parent = view.get("field_parent") or None

        if self.field_parent:
            self.domain = domain

        self.view = view
        self.view_id = view['view_id']

        proxy = rpc.RPCProxy(self.model)

        ctx = dict(self.context,
                   **rpc.session.context)
                
        dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8'))

        root = dom.childNodes[0]
        attrs = node_attributes(root)
        self.string = attrs.get('string', 'Unknown')
        self.toolbar = attrs.get('toolbar', False)

        ids = []
        id = res_id
        
        colors = {}
        for color_spec in attrs.get('colors', '').split(';'):
            if color_spec:
                colour, test = color_spec.split(':')
                colors[colour] = test
                
        if self.toolbar:
            ids = proxy.search(self.domain2, 0, 0, 0, ctx)
            self.toolbar = proxy.read(ids, ['name', 'icon'], ctx)

            if not id and ids:
                id = ids[0]

            if id:
                ids = proxy.read([id], [self.field_parent], ctx)[0][self.field_parent]
        elif not ids:
            ids = proxy.search(domain, 0, 0, 0, ctx)

        self.headers = []
        self.parse(root, fields)

        self.tree = treegrid.TreeGrid(name="tree_%d" % (id),
                                      model=self.model,
                                      headers=self.headers,
                                      url=url("/openerp/tree/data"),
                                      ids=ids,
                                      domain=self.domain,
                                      context=self.context,
                                      field_parent=self.field_parent,
                                      onselection="onSelection",
                                      fields_info=fields_info,
                                      colors=colors)
        self.id = id
        self.ids = ids

        toolbar = {}
        for item, value in view.get('toolbar', {}).items():
            if value: toolbar[item] = value
        if toolbar:
            self.sidebar = Sidebar(self.model, None, toolbar, context=self.context)

        # get the correct view title
        self.string = self.context.get('_terp_view_name', self.string) or self.string