Beispiel #1
0
def export_xls(fieldnames, table):
    try:
        import xlwt
    except ImportError:
        common.error(_('Import Error.'), _('Please install xlwt library to export to MS Excel.'))

    workbook = xlwt.Workbook()
    worksheet = workbook.add_sheet('Sheet 1')

    for i, fieldname in enumerate(fieldnames):
        worksheet.write(0, i, ustr(fieldname))
        worksheet.col(i).width = 8000 # around 220 pixels

    style = xlwt.easyxf('align: wrap yes')

    for row_index, row in enumerate(table):
        for cell_index, cell_value in enumerate(row):
            cell_value = ustr(cell_value)
            cell_value = re.sub("\r", " ", cell_value)
            worksheet.write(row_index + 1, cell_index, cell_value, style)

    fp = StringIO.StringIO()
    workbook.save(fp)
    fp.seek(0)
    data = fp.read()
    return data
Beispiel #2
0
    def display(self, value=None, **params):

        # set editor values
        if not (self.editors and self.edit_inline):
            return super(List, self).display(value, **params)

        ctx = dict(rpc.session.context, **self.context)

        fields = [name for name, _ in chain(self.headers, self.hiddens)]

        proxy = rpc.RPCProxy(self.model)
        if self.edit_inline > 0 and isinstance(self.edit_inline, int) and self.edit_inline in self.data_dict:
            values = self.data_dict[self.edit_inline]
        else:
            values = dict(proxy.default_get(fields, ctx))

            # update values according to domain
            for (field, operator, value) in self.domain:
                if field in fields:
                    if operator == "=":
                        values[field] = value
                    elif operator == "in" and len(value) == 1:
                        values[field] = value[0]

            # call on_change methods
            headers_index = dict([(item[0], item[1]) for item in self.headers])
            to_check = values.keys()
            for field_name in to_check:
                if not field_name in headers_index:
                    continue
                props = headers_index[field_name]
                if not "on_change" in props:
                    continue
                on_change_method = props["on_change"]

                match = re.match("^(.*?)\((.*)\)$", on_change_method)
                if not match:
                    raise common.error(_("Application Error"), _("Wrong on_change trigger"))
                func_name = match.group(1)
                arg_names = [n.strip() for n in match.group(2).split(",")]

                args = [values[arg] if arg in values else False for arg in arg_names]

                proxy = rpc.RPCProxy(self.model)
                response = getattr(proxy, func_name)([], *args)
                if response is False:
                    response = {}
                if "value" not in response:
                    response["value"] = {}

                new_values = response["value"]
                for k, v in new_values.items():
                    if v not in values or values[k] != v:
                        values[k] = v

        for f in fields:
            if f in values:
                self.editors[f].set_value(values[f])

        return super(List, self).display(value, **params)
Beispiel #3
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])]
    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 #5
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 #6
0
    def on_change(self, **kw):

        data = kw.copy()

        callback = data.pop('_terp_callback')
        caller = data.pop('_terp_caller')
        model = data.pop('_terp_model')
        context = data.pop('_terp_context')

        change_default = False
        if '_terp_change_default' in data:
            change_default = data.pop('_terp_change_default')

        try:
            context = eval(context)  # convert to python dict
        except:
            context = {}

        match = re.match('^(.*?)\((.*)\)$', callback)

        if not match:
            raise common.error(_('Application Error'),
                               _('Wrong on_change trigger: %s') % callback)

        for k, v in data.items():
            try:
                data[k] = eval(v)
            except:
                pass

        result = {}

        prefix = ''
        if '/' in caller:
            prefix = caller.rsplit('/', 1)[0]

        ctx = TinyForm(**kw).to_python(safe=True)
        pctx = ctx

        if prefix:
            ctx = ctx.chain_get(prefix)

            if '/' in prefix:
                pprefix = prefix.rsplit('/', 1)[0]
                pctx = pctx.chain_get(pprefix)

        ctx2 = dict(rpc.session.context, **context or {})

        ctx['parent'] = pctx
        ctx['context'] = ctx2

        func_name = match.group(1)
        arg_names = [n.strip() for n in match.group(2).split(',')]

        args = [utils.expr_eval(arg, ctx) for arg in arg_names]
        # TODO: If the eval fails in expr_eval (because `arg` does not exist in `ctx`), it returns `{}`
        # This is a value we don't want, but not sure where that behavior
        # comes from/is used so in order not to risk breakage throughout
        # patch it here
        args = [(False if arg == {} else arg) for arg in args]

        proxy = rpc.RPCProxy(model)

        ids = ctx.id and [ctx.id] or []

        try:
            response = getattr(proxy, func_name)(ids, *args)
        except Exception, e:
            return dict(error=_ep.render())
Beispiel #7
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 #8
0
    def on_change(self, **kw):

        data = kw.copy()

        callback = data.pop('_terp_callback')
        caller = data.pop('_terp_caller')
        model = data.pop('_terp_model')
        context = data.pop('_terp_context')

        try:
            context = eval(context) # convert to python dict
        except:
            context = {}

        match = re.match('^(.*?)\((.*)\)$', callback)

        if not match:
            raise common.error(_('Application Error'), _('Wrong on_change trigger: %s') % callback)

        for k, v in data.items():
            try:
                data[k] = eval(v)
            except:
                pass

        result = {}

        prefix = ''
        if '/' in caller:
            prefix = caller.rsplit('/', 1)[0]

        ctx = TinyForm(**kw).to_python(safe=True)
        pctx = ctx

        if prefix:
            ctx = ctx.chain_get(prefix)

            if '/' in prefix:
                pprefix = prefix.rsplit('/', 1)[0]
                pctx = pctx.chain_get(pprefix)

        ctx2 = dict(rpc.get_session().context,
                    **context or {})

        ctx['parent'] = pctx
        ctx['context'] = ctx2

        func_name = match.group(1)
        arg_names = [n.strip() for n in match.group(2).split(',')]

        args = [utils.expr_eval(arg, ctx) for arg in arg_names]
        # TODO: If the eval fails in expr_eval (because `arg` does not exist in `ctx`), it returns `{}`
        # This is a value we don't want, but not sure where that behavior
        # comes from/is used so in order not to risk breakage throughout
        # patch it here
        args = [(False if arg == {} else arg)
                for arg in args]

        proxy = rpc.RPCProxy(model)

        ids = ctx.id and [ctx.id] or []

        try:
            response = getattr(proxy, func_name)(ids, *args)
        except Exception, e:
             return dict(error=_ep.render())
Beispiel #9
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 #10
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
    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
    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])]
    def display(self, value=None, **params):

        # set editor values
        if not (self.editors and self.edit_inline):
            return super(List, self).display(value, **params)

        ctx = dict(rpc.session.context, **self.context)

        fields = [name for name, _ in chain(self.headers, self.hiddens)]

        proxy = rpc.RPCProxy(self.model)
        if self.edit_inline > 0 and isinstance(self.edit_inline, int) and \
                self.edit_inline in self.data_dict:
            values = self.data_dict[self.edit_inline]
        else:
            values = dict(proxy.default_get(fields, ctx))

            # update values according to domain
            for (field, operator, value) in self.domain:
                if field in fields:
                    if operator == '=':
                        values[field] = value
                    elif operator == 'in' and len(value) == 1:
                        values[field] = value[0]

            #call on_change methods
            headers_index = dict([(item[0], item[1]) for item in self.headers])
            to_check = values.keys()
            for field_name in to_check:
                if not field_name in headers_index:
                    continue
                props = headers_index[field_name]
                if not "on_change" in props:
                    continue
                on_change_method = props["on_change"]

                match = re.match('^(.*?)\((.*)\)$', on_change_method)
                if not match:
                    raise common.error(_('Application Error'),
                                       _('Wrong on_change trigger'))
                func_name = match.group(1)
                arg_names = [n.strip() for n in match.group(2).split(',')]

                args = [
                    values[arg] if arg in values else False
                    for arg in arg_names
                ]

                proxy = rpc.RPCProxy(self.model)
                response = getattr(proxy, func_name)([], *args)
                if response is False:
                    response = {}
                if 'value' not in response:
                    response['value'] = {}

                new_values = response["value"]
                for k, v in new_values.items():
                    if v not in values or values[k] != v:
                        values[k] = v

        for f in fields:
            if f in values:
                self.editors[f].set_value(values[f])

        return super(List, self).display(value, **params)
Beispiel #14
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])]