def parse(self, root, fields): attrs = tools.node_attributes(root) axis = [] axis_data = {} axis_group = {} for node in root.childNodes: attrs = tools.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 parse(self, root, fields): attrs = tools.node_attributes(root) axis = [] axis_data = {} axis_group = {} for node in root.childNodes: attrs = tools.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 parse(self, root, fields): info_fields = [] attrs = tools.node_attributes(root) for node in root.childNodes: attrs = tools.node_attributes(node) if node.localName == 'field': info_fields += [attrs['name']] return info_fields
def __init__(self, model, domain=[], context={}, values={}): super(Search, self).__init__(model=model) self.domain = domain or [] self.context = context or {} ctx = rpc.session.context.copy() ctx.update(self.context) view = cache.fields_view_get(self.model, False, 'tree', ctx, True) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = tools.node_attributes(root) self.string = attrs.get('string', '') self.fields_type = {} self.widgets = [] self.parse(dom, view['fields'], values) # also parse the tree view view = cache.fields_view_get(self.model, False, 'form', ctx, True) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) self.parse(dom, view['fields'], values) self.basic = Frame(children=[w for w in self.widgets if not w.adv]) self.advance = Frame(children=self.widgets)
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 = tools.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 += [node_instance] return result
def __init__(self, model, view=False, view_id=False,view_ids=False, ids=[], domain=[], context={}, width=500, height=350): name = 'graph_%s' % (random.randint(0,10000)) super(Graph, self).__init__(name=name, model=model, width=width, height=height) ctx = rpc.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 = tools.node_attributes(root) self.string = attrs.get('string') chart_type = attrs.get('type', 'pie') self.ids = ids if ids is None: self.ids = rpc.RPCProxy(model).search(domain, 0, 0, 0, ctx) if chart_type == "bar": self.data = BarChart(model, view, view_id, view_ids, ids, domain, context) else: self.data = PieChart(model, view, view_id, ids, domain, context) self.data = simplejson.dumps(self.data.get_data())
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 = tools.xml_locate(xpath_expr, doc)[0] new_node = None record = None if _terp_what == "properties": attrs = tools.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 parse(self, root, fields=None): for node in root.childNodes: if not node.nodeType==node.ELEMENT_NODE: continue attrs = tools.node_attributes(node) field = fields.get(attrs['name']) field.update(attrs) self.headers += [field]
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 = tools.node_attributes(node) name = attrs['name'] fields[name].update(attrs) return 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 = tools.node_attributes(node) name = attrs['name'] fields[name].update(attrs) return fields
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 = tools.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 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 = tools.xml_locate(xpath_expr, doc)[0] attrs = tools.node_attributes(field) editors = [] properties = _PROPERTIES.get(field.localName, []) if field.localName == 'field': kind = 'char' try: model = _get_model(field, parent_model=res['model']) proxy = rpc.RPCProxy(model) attrs2 = proxy.fields_get([attrs['name']])[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 += 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 += [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 = tools.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 __init__(self, model, view=False, view_id=False, view_ids=False, ids=[], domain=[], context={}, width=500, height=350): name = 'graph_%s' % (random.randint(0, 10000)) super(Graph, self).__init__(name=name, model=model, width=width, height=height) ctx = rpc.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 = tools.node_attributes(root) self.string = attrs.get('string') chart_type = attrs.get('type', 'pie') self.ids = ids if ids is None: self.ids = rpc.RPCProxy(model).search(domain, 0, 0, 0, ctx) if chart_type == "bar": self.data = BarChart(model, view, view_id, view_ids, ids, domain, context) else: self.data = PieChart(model, view, view_id, ids, domain, context) self.data = simplejson.dumps(self.data.get_data())
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 [] if name.endswith('/'): self._name = name[:-1] if name != '_terp_list': self.source = self.name.replace('/', '/') or None self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 0) self.count = kw.get('count', 0) self.link = kw.get('nolinks', 1) self.attr_limit = 0 self.m2m = False self.concurrency_info = None self.selector = None 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 = tools.node_attributes(root) self.string = attrs.get('string', '') # is relational field (M2M/O2M) if self.source: self.attr_limit = cherrypy.request.app.config['openerp-web'].get( 'child.listgrid.limit', 20) self.attr_limit = int(attrs.get('limit', self.attr_limit)) else: self.min_rows = 5 try: self.min_rows = int(attrs.get('min_rows')) except: pass try: if self.limit == 0: self.limit = self.attr_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) if ids == None: if self.limit > 0: ids = proxy.search(domain, self.offset, self.limit, 0, context) else: ids = proxy.search(domain, 0, 0, 0, context) self.count = proxy.search_count(domain, 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) if self.limit and len(ids) > self.limit and self.limit != -1: new_ids = ids[self.offset:self.offset + self.limit] data = proxy.read(new_ids, fields.keys() + ['__last_update'], ctx) else: data = proxy.read(ids, fields.keys() + ['__last_update'], ctx) self._update_concurrency_info(self.model, data) self.concurrency_info = ConcurrencyInfo(self.model, ids) for item in data: self.data_dict[item['id']] = item.copy() self.ids = ids 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(): 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, def_limit=self.attr_limit) self.pager._name = self.name # make editors if self.editable and attrs.get('editable') in ('top', 'bottom'): for f, fa in self.headers: k = fa.get('type', 'char') if k not in form.WIDGETS: k = 'char' fa['prefix'] = '_terp_listfields' + ( (self.name != '_terp_list' or '') and '/' + self.name) fa['inline'] = True self.editors[f] = form.WIDGETS[k](**fa) # generate hidden fields for f, fa in self.hiddens: k = fa.get('type', 'char') if k not in form.WIDGETS: k = 'char' 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=None, fields=None, values={}): for node in root.childNodes: if not node.nodeType==node.ELEMENT_NODE: continue attrs = tools.node_attributes(node) if attrs.has_key('colspan'): attrs['colspan'] = 1 if attrs.has_key('nolabel'): attrs['nolabel'] = False if node.localName in ('form', 'tree'): self.parse(root=node, fields=fields, values=values) #views += [Frame(attrs, n)] elif node.localName == 'notebook': self.parse(root=node, fields=fields, values=values) elif node.localName == 'page': self.parse(root=node, fields=fields, values=values) elif node.localName=='group': self.parse(root=node, fields=fields, values=values) elif node.localName == 'field': name = attrs['name'] if name in self.fields_type: continue if not ('select' in attrs or 'select' in fields[name]): continue if attrs.get('widget', False): if attrs['widget']=='one2many_list': attrs['widget']='one2many' attrs['type'] = attrs['widget'] # in search view fields should be writable attrs['readonly'] = False attrs['required'] = False attrs['translate'] = False attrs['disabled'] = False attrs['visible'] = True attrs['invisible'] = False attrs['editable'] = True attrs['attrs'] = None attrs['states'] = None try: fields[name].update(attrs) except: print "-"*30,"\n malformed tag for:", attrs print "-"*30 raise kind = fields[name]['type'] if kind not in WIDGETS: continue self.fields_type[name] = kind field = WIDGETS[kind](**fields[name]) field.onchange = None field.callback = None val = fields[name].get('select', False) field.adv = val and int(val) > 1 if kind == 'boolean': field.options = [[1,'Yes'],[0,'No']] field.validator.if_empty = '' if kind =='selection' and field.name in ('state','project_status'): #negative_state = field.options add_list_temp = [] for tmp_lst in field.options: add_list_temp.append(("kdvn_not_"+tmp_lst[0],"Not - "+tmp_lst[1])) field.options.extend(add_list_temp) if values.has_key(name) and isinstance(field, (TinyInputWidget, RangeWidget)): field.set_value(values[name]) self.widgets += [field]
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 proxy = rpc.RPCProxy(model) view_id = view.get('view_id', False) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = tools.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 ] fields = list(set([x for x in fields if x])) self.fields = proxy.fields_get(fields) 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, prefix, model, view, ids=[], domain=[], context={}, editable=True, readonly=False, nodefault=False, nolinks=1, is_wizard=False): 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 = tools.node_attributes(root) fields = view['fields'] self.string = attrs.get('string', '') self.link = attrs.get('link', nolinks) self.is_wizard = is_wizard self.id = None self.context = context or {} proxy = rpc.RPCProxy(model) ctx = rpc.session.context.copy() ctx.update(context) ctx['bin_size'] = True values = {} defaults = {} # update values according to domain for d in domain: if d[0] in fields: if d[1] == '=': values[d[0]] = d[2] if d[1] == 'in' and len(d[2]) == 1: values[d[0]] = d[2][0] if ids: lval = proxy.read(ids[:1], fields.keys() + ['__last_update'], ctx) if lval: values = lval[0] self.id = ids[0] self._update_concurrency_info(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 = proxy.default_get(fields.keys(), ctx) elif 'state' in fields: # if nodefault and state get state only defaults = proxy.default_get(['state'], ctx) elif 'x_state' in fields: # if nodefault and x_state get x_state only (for custom objects) defaults = proxy.default_get(['x_state'], ctx) for k, v in defaults.items(): values.setdefault(k, v) self.state = values.get('state', values.get('x_state')) # store current record values in request object (see, self.parse & O2M default_get_ctx) if not hasattr(cherrypy.request, 'terp_record'): cherrypy.request.terp_record = TinyDict() self.view_fields = [] self.nb_couter = 0 self.frame = self.parse(prefix, dom, fields, values)[0] self.values = [values] self.concurrency_info = ConcurrencyInfo(self.model, [self.id]) # We should generate hidden fields for fields which are not in view, as # the values of such fields might be used during `onchange` for name, attrs in fields.items(): if name not in self.view_fields: kind = attrs.get('type', 'char') if kind not in WIDGETS: continue attrs['prefix'] = prefix attrs['name'] = name attrs['readonly'] = True # always make them readonly field = self._make_field_widget(attrs, values.get(name)) self.frame.add_hidden(field)
def __init__(self, view, model, res_id=False, domain=[], context={}, action=None): super(ViewTree, self).__init__(name='view_tree', action=action) self.model = view['model'] self.domain2 = domain or [] self.context = context or {} self.domain = [] 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 = self.context.copy(); ctx.update(rpc.session.context) fields = cache.fields_get(self.model, False, ctx) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = tools.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", model=self.model, headers=self.headers, url="/tree/data", ids=ids or 0, domain=self.domain, context=self.context, field_parent=self.field_parent, onselection="onSelection", onheaderclick="onHeaderClick") self.id = id self.ids = ids toolbar = {} for item, value in view.get('toolbar', {}).items(): if value: toolbar[item] = value self.sidebar = Sidebar(self.model, toolbar, context=self.context) # get the correct view title self.string = self.context.get('_terp_view_name', self.string) or self.string
def __init__(self, model, view=False, view_id=False, ids=[], domain=[], context={}): ctx = {} ctx = rpc.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 = tools.node_attributes(root) self.model = model self.string = attrs.get('string', 'Unknown') self.kind = attrs.get('type', '') self.orientation = attrs.get('orientation', 'vertical') self.values = [] axis, axis_data, axis_group = self.parse(root, fields) proxy = rpc.RPCProxy(model) ctx = rpc.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': for i in fields[x]['selection']: if value[x] in i: res[x] = i[1] elif fields[x]['type'] == 'date': if value[x]: date = time.strptime(value[x], DT_FORMAT) 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], DHM_FORMAT) if 'tz' in rpc.session.context: try: import pytz lzone = pytz.timezone(rpc.session.context['tz']) szone = pytz.timezone(rpc.session.timezone) dt = DT.datetime(date[0], date[1], date[2], date[3], date[4], date[5], date[6]) sdt = szone.localize(dt, is_dst=True) ldt = sdt.astimezone(lzone) date = ldt.timetuple() except: pass res[x] = time.strftime(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')+' %H:%M:%S', date) else: res[x] = '' else: res[x] = float(value[x]) 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 __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 proxy = rpc.RPCProxy(model) view_id = view.get('view_id', False) dom = xml.dom.minidom.parseString(view['arch'].encode('utf-8')) root = dom.childNodes[0] attrs = tools.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] fields = list(set([x for x in fields if x])) self.fields = proxy.fields_get(fields) 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, 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 = tools.node_attributes(node) buttons += [Button(**attrs)] elif node.nodeName == 'field': attrs = tools.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', False): 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) invisible = False try: visval = fields[name].get('invisible', 'False') invisible = eval(visval, {'context': self.context}) except: pass if invisible: hiddens += [(name, fields[name])] continue if 'sum' in attrs: field_total[name] = [attrs['sum'], 0.0] for i, row in enumerate(data): row_value = values[i] cell = CELLTYPES[kind](value=row_value.get( name, False), **fields[name]) for color, expr in self.colors.items(): try: d = row_value.copy() d['current_date'] = time.strftime('%Y-%m-%d') d['time'] = time d['active_id'] = rpc.session.active_id or False if tools.expr_eval(expr, d): cell.color = color break except: pass row[name] = cell headers += [(name, fields[name])] return headers, hiddens, data, field_total, buttons
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 [] if name.endswith('/'): self._name = name[:-1] if name != '_terp_list': self.source = self.name.replace('/', '/') or None self.selectable = kw.get('selectable', 0) self.editable = kw.get('editable', False) self.pageable = kw.get('pageable', True) self.alt='' self.offset = kw.get('offset', 0) self.limit = kw.get('limit', 0) self.count = kw.get('count', 0) self.link = kw.get('nolinks', 1) self.attr_limit = 0 self.m2m = False self.concurrency_info = None self.selector = None 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 = tools.node_attributes(root) self.string = attrs.get('string','') # is relational field (M2M/O2M) if self.source: self.attr_limit = cherrypy.request.app.config['openerp-web'].get('child.listgrid.limit', 20) self.attr_limit = int(attrs.get('limit', self.attr_limit)) else: self.min_rows = 5 try: self.min_rows = int(attrs.get('min_rows')) except: pass try: if self.limit == 0: self.limit = self.attr_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) if ids == None: if self.limit > 0: ids = proxy.search(domain, self.offset, self.limit, 0, context) else: ids = proxy.search(domain, 0, 0, 0, context) self.count = proxy.search_count(domain, 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) if self.limit and len(ids) > self.limit and self.limit != -1: new_ids = ids[self.offset:self.offset+self.limit] data = proxy.read(new_ids, fields.keys() + ['__last_update'], ctx) else: data = proxy.read(ids, fields.keys() + ['__last_update'], ctx) self._update_concurrency_info(self.model, data) self.concurrency_info = ConcurrencyInfo(self.model, ids) for item in data: self.data_dict[item['id']] = item.copy() self.ids = ids 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(): 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, def_limit=self.attr_limit) self.pager._name = self.name # make editors if self.editable and attrs.get('editable') in ('top', 'bottom'): for f, fa in self.headers: k = fa.get('type', 'char') if k not in form.WIDGETS: k = 'char' if k=='integer': fa['alt'] = 'integer' elif k=='float': fa['alt'] = 'number' elif k=='date': fa['alt'] = 'date' fa['prefix'] = '_terp_listfields' + ((self.name != '_terp_list' or '') and '/' + self.name) fa['inline'] = True self.editors[f] = form.WIDGETS[k](**fa) # generate hidden fields for f, fa in self.hiddens: k = fa.get('type', 'char') if k not in form.WIDGETS: k = 'char' 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, prefix='', root=None, fields=None, values={}): views = [] for node in root.childNodes: if not node.nodeType==node.ELEMENT_NODE: continue attrs = tools.node_attributes(node) attrs['prefix'] = prefix attrs['state'] = self.state if node.localName=='image': views += [Image(**attrs)] elif node.localName=='separator': views += [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 += [Label(**attrs)] elif node.localName=='newline': views += [NewLine(**attrs)] elif node.localName=='button': views += [Button(model=self.model, id=self.id, **attrs)] elif node.localName == 'form': n = self.parse(prefix=prefix, root=node, fields=fields, values=values) views += [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 += [nb] elif node.localName == 'page': n = self.parse(prefix=prefix, root=node, fields=fields, values=values) views += [Page(children=n, **attrs)] elif node.localName=='group': n = self.parse(prefix=prefix, root=node, fields=fields, values=values) views += [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 kind not in WIDGETS: continue if kind in ('text', 'text_tag') and attrs.get('html'): kind = 'text_html' 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 += [field] elif node.localName=='hpaned': n = self.parse(prefix=prefix, root=node, fields=fields, values=values) views += [HPaned(children=n, **attrs)] elif node.localName=='vpaned': n = self.parse(prefix=prefix, root=node, fields=fields, values=values) views += [VPaned(children=n, **attrs)] elif node.localName in ('child1', 'child2'): n = self.parse(prefix=prefix, root=node, fields=fields, values=values) attrs['name'] = tools.get_node_xpath(node) views += [Dashbar(children=n, **attrs)] elif node.localName=='action': views += [Action(**attrs)] cherrypy.request._terp_dashboard = True return views
def parse(self, root=None, fields=None, values={}): for node in root.childNodes: if not node.nodeType == node.ELEMENT_NODE: continue attrs = tools.node_attributes(node) if attrs.has_key('colspan'): attrs['colspan'] = 1 if attrs.has_key('nolabel'): attrs['nolabel'] = False if node.localName in ('form', 'tree'): self.parse(root=node, fields=fields, values=values) #views += [Frame(attrs, n)] elif node.localName == 'notebook': self.parse(root=node, fields=fields, values=values) elif node.localName == 'page': self.parse(root=node, fields=fields, values=values) elif node.localName == 'group': self.parse(root=node, fields=fields, values=values) elif node.localName == 'field': name = attrs['name'] if name in self.fields_type: continue if not ('select' in attrs or 'select' in fields[name]): continue if attrs.get('widget', False): if attrs['widget'] == 'one2many_list': attrs['widget'] = 'one2many' attrs['type'] = attrs['widget'] # in search view fields should be writable attrs['readonly'] = False attrs['required'] = False attrs['translate'] = False attrs['disabled'] = False attrs['visible'] = True attrs['invisible'] = False attrs['editable'] = True attrs['attrs'] = None try: fields[name].update(attrs) except: print "-" * 30, "\n malformed tag for:", attrs print "-" * 30 raise kind = fields[name]['type'] if kind not in WIDGETS: continue self.fields_type[name] = kind field = WIDGETS[kind](**fields[name]) field.onchange = None field.callback = None val = fields[name].get('select', False) field.adv = val and int(val) > 1 if kind == 'boolean': field.options = [[1, 'Yes'], [0, 'No']] field.validator.if_empty = '' if values.has_key(name) and isinstance( field, (TinyInputWidget, RangeWidget)): field.set_value(values[name]) self.widgets += [field]
def __init__(self, model, view=False, view_id=False, ids=[], domain=[], context={}): ctx = {} ctx = rpc.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 = tools.node_attributes(root) self.model = model self.string = attrs.get('string', 'Unknown') self.kind = attrs.get('type', '') self.orientation = attrs.get('orientation', 'vertical') self.values = [] axis, axis_data, axis_group = self.parse(root, fields) proxy = rpc.RPCProxy(model) ctx = rpc.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': for i in fields[x]['selection']: if value[x] in i: res[x] = i[1] elif fields[x]['type'] == 'date': if value[x]: date = time.strptime(value[x], DT_FORMAT) 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], DHM_FORMAT) if 'tz' in rpc.session.context: try: import pytz lzone = pytz.timezone( rpc.session.context['tz']) szone = pytz.timezone(rpc.session.timezone) dt = DT.datetime(date[0], date[1], date[2], date[3], date[4], date[5], date[6]) sdt = szone.localize(dt, is_dst=True) ldt = sdt.astimezone(lzone) date = ldt.timetuple() except: pass res[x] = time.strftime( locale.nl_langinfo(locale.D_FMT).replace( '%y', '%Y') + ' %H:%M:%S', date) else: res[x] = '' else: res[x] = float(value[x]) 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, 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 = tools.node_attributes(node) buttons += [Button(**attrs)] elif node.nodeName == 'field': attrs = tools.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', False): 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) invisible = False try: visval = fields[name].get('invisible', 'False') invisible = eval(visval, {'context': self.context}) except: pass if invisible: hiddens += [(name, fields[name])] continue if 'sum' in attrs: field_total[name] = [attrs['sum'], 0.0] for i, row in enumerate(data): row_value = values[i] cell = CELLTYPES[kind](value=row_value.get(name, False), **fields[name]) for color, expr in self.colors.items(): try: d = row_value.copy() d['current_date'] = time.strftime('%Y-%m-%d') d['time'] = time d['active_id'] = rpc.session.active_id or False if tools.expr_eval(expr, d): cell.color = color break except: pass row[name] = cell headers += [(name, fields[name])] return headers, hiddens, data, field_total, buttons