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))
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
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
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=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
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())
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
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
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
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))
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)
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'])
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)
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 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 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)
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)
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)
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
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
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 __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])]
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))]
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, 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 __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))]
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
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)
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)
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 __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))]
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, 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 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 __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
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))]
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
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