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
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)
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])]
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
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())
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])]
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())
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])]
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)
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])]