Пример #1
0
    def update_dashboard(self, view_id, dst, src, ref=None):
        error = None

        view_id = int(view_id)

        views = rpc.RPCProxy('ir.ui.view')
        data = views.read([view_id])[0]

        doc = xml.dom.minidom.parseString(data['arch'].encode('utf-8'))
        pnode = utils.xml_locate(dst, doc)[0]
        src = xml_getElementsByTagAndName('*', src, doc)[0]

        if ref: ref = xml_getElementsByTagAndName('*', ref, doc)[0]
        pnode.insertBefore(src, ref)
        del data['id']

        try:
            views.write(view_id, {'arch': doc.toxml(encoding="utf-8")})
        except Exception, e:
            error = str(e)
Пример #2
0
    def __init__(self,
                 model,
                 submenu=None,
                 toolbar=None,
                 id=None,
                 view_type="form",
                 multi=True,
                 context=None,
                 **kw):
        super(Sidebar, self).__init__(model=model, id=id)
        self.multi = multi
        self.context = context or {}
        self.ctx = context
        self.view_type = view_type
        toolbar = toolbar or {}
        submenu = submenu
        self.id = id or None
        self.reports = toolbar.get('print', [])
        self.actions = toolbar.get('action', [])
        self.relates = toolbar.get('relate', [])
        self.attachments = []
        self.sub_menu = None

        action = 'client_action_multi'
        if self.view_type == 'form':
            action = 'tree_but_action'
        self.add_remote_action_values(action, self.actions)

        self.add_remote_action_values('client_print_multi', self.reports)

        if self.view_type == 'form' and id:
            attachments = rpc.RPCProxy('ir.attachment')
            attachment_ids = attachments.search(
                [('res_model', '=', model), ('res_id', '=', id),
                 ('type', 'in', ['binary', 'url'])], 0, 0, 0, self.context)

            if attachment_ids:
                self.attachments = attachments.read(attachment_ids,
                                                    ['name', 'url', 'type'])

            self.sub_menu = submenu
    def get(self, id, res_model=None, res_id=False, title=None):

        id = int(id)
        res_id = eval(str(res_id))

        proxy = rpc.RPCProxy('process.process')
        graph = proxy.graph_get(id, res_model, res_id, (80, 80, 150, 100), rpc.session.context)

        related = (res_model or None) and proxy.search_by_model(res_model, rpc.session.context)
        graph['related'] = dict(related or {})

        if graph.get('resource'):
            graph['title'] = _("%(name)s - Resource: %(resource)s, State: %(state)s") % graph
        else:
            graph['title'] = graph['name']

        def update_perm(perm):
            perm = perm or {}

            try:
                perm['date'] = format.format_datetime(perm['write_date'] or perm['create_date'])
            except:
                pass

            perm['text'] = _("Last modified by:")
            perm['value'] = perm.get('write_uid') or perm.get('create_uid')
            if perm['value']:
                perm['value'] =  '%s (%s)' % (perm['value'][1], perm.get('date') or 'N/A')
            else:
                perm['value'] = 'N/A'

            return perm

        # last modified by
        graph['perm'] = update_perm(graph['perm'] or {})
        for nid, node in graph['nodes'].items():
            if not node.get('res'):
                continue
            node['res']['perm'] = update_perm(node['res']['perm'] or {})

        return graph
    def get_new_modules(self):
        if not addons.writeable: return []
        modules = rpc.RPCProxy('ir.module.module')
        web_modules = modules.list_web()
        if not web_modules: return []
        addons_to_load = map(operator.itemgetter(0), web_modules)

        addons_to_download = [
            name for (name, version) in web_modules
            if (not addons.exists(name)
                or version > addons.get_info(name).get('version', '0'))
        ]
        # avoid querying for 0 addons if we have everything already
        if not addons_to_download: return addons_to_load
        web_payload = modules.get_web(addons_to_download)
        for module in web_payload:
            # Due to the way zip_directory works on the server, we get a toplevel dir called "web" for our addon,
            # rather than having it named "the right way". Dump to temp directory and move to right name.
            temp_dir = tempfile.mkdtemp()
            extract_zip_file(StringIO(module['content'].decode('base64')),
                             temp_dir)

            # cleanup any existing addon of the same name
            module_dir = paths.addons(module['name'])
            shutil.rmtree(module_dir, ignore_errors=True)

            shutil.move(os.path.join(temp_dir, 'web'), module_dir)
            shutil.rmtree(temp_dir)

            dependencies = map(lambda u: u.encode('utf-8'), module['depends'])
            descriptor = open(os.path.join(module_dir, '__openerp__.py'), 'wb')
            descriptor.write('# -*- coding: utf-8 -*-\n')
            descriptor.write("%s" % (
                {
                    'name': module['name'].encode('utf-8'),
                    'version': module['version'].encode('utf-8'),
                    # addons depend at least of openerp
                    'depends': dependencies or ['openerp'],
                }, ))
            descriptor.close()
        return addons_to_load
    def save(self, terp_save_only=False, **kw):
        params, data = TinyDict.split(kw)

        # remember the current page (tab) of notebooks
        cherrypy.session['remember_notebooks'] = True

        # bypass save, for button action in non-editable view
        if not (params.button and not params.editable and params.id):

            proxy = rpc.RPCProxy(params.model)

            if not params.id:
                id = proxy.create(data, params.context)
                params.ids = (params.ids or []) + [int(id)]
                params.id = int(id)
                params.count += 1
            else:
                ctx = context_with_concurrency_info(params.context,
                                                    params.concurrency_info)
                id = proxy.write([params.id], data, ctx)

        button = (params.button or False) and True

        # perform button action
        if params.button:
            res = self.button_action(params)
            if res:
                return res

        current = params.chain_get(params.source or '')
        if current:
            current.id = None
            if not params.id:
                params.id = int(id)
        elif not button:
            params.editable = False

        if not current and not button:
            params.load_counter = 2

        return self.create(params)
Пример #6
0
    def count_sum(self, model, ids, sum_fields):
        selected_ids = ast.literal_eval(ids)
        sum_fields = sum_fields.split(",")
        ctx = rpc.session.context.copy()

        proxy = rpc.RPCProxy(model)
        res = proxy.read(selected_ids, sum_fields, ctx)

        total = []
        for field in sum_fields:
            total.append([])

        for i in range(len(selected_ids)):
            for k in range(len(sum_fields)):
                total[k].append(res[i][sum_fields[k]])

        total_sum = []
        for s in total:
            total_sum.append(str(sum(s)))

        return dict(sum=total_sum)
Пример #7
0
    def exp(self, import_compat="1", **kw):

        params, data = TinyDict.split(kw)
        ctx = dict((params.context or {}), **rpc.session.context)

        if ctx.get("group_by_no_leaf", 0):
            raise common.warning(_("You cannot export these record(s) !"),
                                 _('Error'))

        views = {}
        if params.view_mode and params.view_ids:
            for i, view in enumerate(params.view_mode):
                views[view] = params.view_ids[i]

        exports = rpc.RPCProxy('ir.exports')

        headers = [{'string': 'Name', 'name': 'name', 'type': 'char'}]
        tree = treegrid.TreeGrid('export_fields',
                                 model=params.model,
                                 headers=headers,
                                 url=tools.url('/openerp/impex/get_fields'),
                                 field_parent='relation',
                                 context=ctx,
                                 views=views,
                                 import_compat=int(import_compat))

        tree.show_headers = False

        existing_exports = exports.read(
            exports.search([('resource', '=', params.model)], context=ctx), [],
            ctx)

        return dict(existing_exports=existing_exports,
                    model=params.model,
                    ids=params.ids,
                    ctx=ctx,
                    search_domain=params.search_domain,
                    source=params.source,
                    tree=tree,
                    import_compat=import_compat)
Пример #8
0
    def save_exp(self, **kw):
        params, data = TinyDict.split(kw)

        selected_list = data.get('fields')
        name = data.get('savelist_name')

        proxy = rpc.RPCProxy('ir.exports')

        if selected_list and name:
            if isinstance(selected_list, basestring):
                selected_list = [selected_list]
            proxy.create({
                'name':
                name,
                'resource':
                params.model,
                'export_fields': [(0, 0, {
                    'name': f
                }) for f in selected_list]
            })

        raise redirect('/openerp/impex/exp', **kw)
Пример #9
0
    def get(self, **kw):

        params, data = TinyDict.split(kw)

        error = None
        error_field = None

        model = params.model

        record = kw.get('record')
        record = eval(record)
        proxy = rpc.RPCProxy(model)
        data = {}
        res = proxy.fields_get(False, rpc.session.context)

        all_values = {}
        errors = []
        for k, v in record.items():
            values = {}
            for key, val in v.items():
                for field in val:
                    fld = {'value': val[field], 'type': res[field].get('type')}
                    if fld['type'] == 'many2many':
                        fld['type'] = 'char'
                    datas = {field: fld}

                    try:
                        TinyForm(**datas).to_python()
                    except TinyFormError, e:
                        errors.append({e.field: ustr(e)})
                    except Exception, e:
                        errors.append({field: ustr(e)})

                    datas['rec'] = field

                    datas['rec_val'] = fld['value']

                datas['type'] = fld['type']
                values[key] = datas
Пример #10
0
    def create(self, params, tg_errors=None):

        params.view_mode = ['tree', 'form']
        params.view_type = 'tree'

        params.offset = params.offset or 0
        params.limit = params.limit or 50
        params.count = params.count or 0
        params.filter_domain = params.filter_domain or []
        params.editable = 0

        form = self.create_form(params, tg_errors)

        # don't show links in list view, except the do_select link
        form.screen.widget.show_links = 0
        if params.get('return_to'):
            proxy = rpc.RPCProxy(params.model)
            records = proxy.read(params.ids, ['name'], rpc.session.context)
            params['grp_records'] = records
        return dict(form=form,
                    params=params,
                    form_name=form.screen.widget.name)
Пример #11
0
    def get_groups(self, events):

        if not self.level:
            return []

        obj = self.level['object']
        field = self.level['link']

        keys = []
        groups = {}
        for evt in events:
            group_id = evt.record[field]
            group_title = 'None'

            if not group_id:  # create dummy group
                group_id = 0

            if isinstance(group_id, (list, tuple)):
                group_id, group_title = evt.record[field]
            elif group_id:
                group_id, group_title = rpc.RPCProxy(obj).name_get(
                    [group_id], rpc.session.context)[0]

            group = groups.setdefault(
                group_id, {
                    'id': str(group_id),
                    'title': group_title,
                    'model': obj,
                    'items': []
                })

            group['items'].append(str(evt.record_id))

            if group_id not in keys:
                keys.append(group_id)

        return [groups[i] for i in keys]
Пример #12
0
    def menu(self, active=None, next=None):
        try:
            menu_id = int(active)
        except (TypeError, ValueError):
            menu_id = False

        menus = rpc.RPCProxy("ir.ui.menu")
        ids = menus.search([('parent_id', '=', False)])
        if next or active:
            if not menu_id and ids:
                menu_id = ids[0]

        menu = ''
        if menu_id:
            ctx = dict(
                lang='NO_LANG'
            )  # force loading original string even if the english have been translated...
            menu = menus.read([menu_id], ['name'], ctx)[0]['name'] or ''

        general_forum = 77459
        forum = {
            'accounting': 87921,
            'administration': 87935,
            'human resources': 87923,
            'knowledge': 87927,
            'manufacturing': 87915,
            'marketing': 87925,
            'point of sale': 87929,
            'project': 87919,
            'purchases': 87911,
            'sales': 87907,
            'tools': 87933,
            'warehouse': 87913,
        }.get(menu.lower().strip(), general_forum)

        cherrypy.request.uservoice_forum = forum
        return super(Root, self).menu(active, next)
Пример #13
0
    def duplicate(self, **kw):
        params, data = TinyDict.split(kw)

        if not params.ids:
            params.ids = []

        id = params.id
        ctx = params.context
        model = params.model

        proxy = rpc.RPCProxy(model)
        new_id = proxy.copy(id, {}, ctx)

        if new_id:
            params.id = new_id
            params.ids += [int(new_id)]
            params.count += 1

        args = {
            'model': params.model,
            'id': params.id,
            'ids': ustr(params.ids),
            'view_ids': ustr(params.view_ids),
            'view_mode': ustr(params.view_mode),
            'domain': ustr(params.domain),
            'context': ustr(params.context),
            'offset': params.offset,
            'limit': params.limit,
            'count': params.count,
            'search_domain': ustr(params.search_domain),
            'filter_domain': ustr(params.filter_domain)
        }

        if new_id:
            raise redirect(self.path + '/edit', **args)

        raise redirect(self.path + '/view', **args)
Пример #14
0
def _fields_get_all(model, views, context=None):

    context = context or {}

    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 get_view_fields(view):
        return parse(
            xml.dom.minidom.parseString(
                view['arch'].encode('utf-8')).documentElement, view['fields'])

    proxy = rpc.RPCProxy(model)

    tree_view = proxy.fields_view_get(views.get('tree', False), 'tree',
                                      context)
    form_view = proxy.fields_view_get(views.get('form', False), 'form',
                                      context)

    fields = {}
    fields.update(get_view_fields(tree_view))
    fields.update(get_view_fields(form_view))

    return fields
Пример #15
0
    def __init__(self, **attrs):

        super(Action, self).__init__(**attrs)
        self.nolabel = True

        self.act_id= self.name
        
        proxy = rpc.RPCProxy("ir.actions.actions")
        res = proxy.read([self.act_id], ['type'], rpc.session.context)
        if not res:
            raise common.message(_('Action not found'))

        _type=res[0]['type']
        self.action = rpc.session.execute('object', 'execute', _type, 'read', [self.act_id], False, rpc.session.context)[0]

        if 'view_mode' in attrs:
            self.action['view_mode'] = attrs['view_mode']

        if self.action['type']=='ir.actions.act_window':

            if not self.action.get('domain', False):
                self.action['domain']='[]'

            ctx = dict(rpc.session.context,
                       active_id=False,
                       active_ids=[])

            self.context = expr_eval(self.action.get('context', '{}'), ctx)
            self.domain = expr_eval(self.action['domain'], ctx)
            views = dict(map(lambda x: (x[1], x[0]), self.action['views']))
            view_mode = self.action.get('view_mode', 'tree,form').split(',')
            view_ids = map(lambda x: views.get(x, False), view_mode)
            
            if views.keys() != view_mode:
                view_mode = map(lambda x: x[1], self.action['views'])
                view_ids = map(lambda x: x[0], self.action['views'])
            
            if self.action['view_type'] == 'form':

                params = TinyDict()
                params.updateAttrs(
                    model=self.action['res_model'],
                    id=False,
                    ids=None,
                    view_ids=view_ids,
                    view_mode=view_mode,
                    context=self.context,
                    domain=self.domain,
                    offset = 0,
                    limit = 50
                )

                # get pager vars if set
                if hasattr(cherrypy.request, 'terp_params'):
                    current = cherrypy.request.terp_params
                    current = current.chain_get(self.name or '') or current

                    params.updateAttrs(
                        offset=current.offset,
                        limit=current.limit
                    )

                self.screen = screen.Screen(params, prefix=self.name, editable=True, selectable=3)

            elif self.action['view_type']=='tree':
                pass #TODO
Пример #16
0
    def view_get(self, view_id=None):
        def _inherit_apply(src, inherit, inherited_id):
            def _find(node, node2):
                # Check if xpath query or normal inherit (with field matching)
                if node2.nodeType == node2.ELEMENT_NODE and node2.localName == 'xpath':
                    res = utils.get_xpath(node2.getAttribute('expr'), node)
                    return res and res[0]
                else:
                    if node.nodeType == node.ELEMENT_NODE and node.localName == node2.localName:
                        res = True
                        for attr in node2.attributes.keys():
                            if attr == 'position':
                                continue
                            if node.hasAttribute(attr):
                                if node.getAttribute(
                                        attr) == node2.getAttribute(attr):
                                    continue
                            res = False
                        if res:
                            return node
                    for child in node.childNodes:
                        res = _find(child, node2)
                        if res: return res
                return None

            doc_src = xml.dom.minidom.parseString(src.encode('utf-8'))
            doc_dest = xml.dom.minidom.parseString(inherit.encode('utf-8'))
            for node2 in doc_dest.childNodes:

                if node2.localName == 'data':
                    continue
                if not node2.nodeType == node2.ELEMENT_NODE:
                    continue
                node = _find(doc_src, node2)
                if node:
                    vnode = doc_dest.createElement('view')
                    vnode.setAttribute('view_id', str(inherited_id))
                    vnode.appendChild(node2)
                    node.appendChild(vnode)
                else:
                    attrs = ''.join([
                        ' %s="%s"' % (attr, node2.getAttribute(attr))
                        for attr in node2.attributes.keys()
                        if attr != 'position'
                    ])
                    tag = "<%s%s>" % (node2.localName, attrs)
                    raise AttributeError, "Couldn't find tag '%s' in parent view" % tag
            return doc_src.toxml().replace('\t', '')

        views = rpc.RPCProxy('ir.ui.view')
        res = views.read([view_id])[0]

        def _inherit_apply_rec(result, inherit_id):
            # get all views which inherit from (ie modify) this view
            inherit_ids = views.search([('inherit_id', '=', inherit_id)], 0, 0,
                                       'priority')
            inherit_res = views.read(inherit_ids, ['arch', 'id'])

            for res2 in inherit_res:
                result = _inherit_apply(result, res2['arch'], res2['id'])
                result = _inherit_apply_rec(result, res2['id'])

            return result

        doc_arch = _inherit_apply_rec(res['arch'], view_id)
        doc_arch = xml.dom.minidom.parseString(doc_arch.encode('utf-8'))

        new_doc = xml.dom.getDOMImplementation().createDocument(
            None, 'view', None)
        new_doc.documentElement.setAttribute('view_id', str(view_id))
        new_doc.documentElement.appendChild(doc_arch.documentElement)

        return {
            'model': res['model'],
            'view_id': view_id,
            'view_type': res['type'],
            'arch': new_doc.toxml().replace('\t', '')
        }
Пример #17
0
 def remove_log(self, log_id):
     error = None
     try:
         rpc.RPCProxy('publisher_warranty.contract').del_user_message(log_id)
     except Exception, e:
         error = e
def parse_groups(group_by, grp_records, headers, ids, model, offset, limit,
                 context, data, total_fields, fields):
    proxy = rpc.RPCProxy(model)
    grouped = []
    grp_ids = []
    for grp in grp_records:
        inner = {}
        for key, head in headers:
            if not isinstance(head, int):
                kind = head.get('type')
                if kind == 'progressbar':
                    inner[key] = CELLTYPES[kind](value=grp.get(key), **head)
        grouped.append(inner)

    child = len(group_by) == 0
    digits = (16, 2)
    if fields:
        for key, val in fields.items():
            if val.get('digits'):
                digits = val['digits']
    if isinstance(digits, basestring):
        digits = eval(digits)
    integer, digit = digits

    if grp_records and total_fields and group_by:
        for sum_key, sum_val in total_fields.items():
            if grp_records[0].has_key(sum_key):
                value = sum(map(lambda x: x[sum_key], grp_records))
                if isinstance(value, float):
                    total_fields[sum_key][1] = format.format_decimal(
                        value or 0.0, digit)
                else:
                    total_fields[sum_key][1] = value
    if grp_records:
        for rec in grp_records:
            for key, val in rec.items():
                if isinstance(val, float):
                    rec[key] = format.format_decimal(val or 0.0, digit)

            for grp_by in group_by:
                if fields.get(grp_by).get(
                        'type') == 'boolean' and grp_by in rec and rec.get(
                            grp_by) == False:
                    rec[grp_by] = 'False'
                elif not rec.get(grp_by):
                    rec[grp_by] = ''

            ch_ids = []
            if child:
                rec_dom = rec.get('__domain')
                dom = [('id', 'in', ids)] + rec_dom
                ch_ids = [
                    d for id in proxy.search(dom, offset, limit, 0, context)
                    for d in data if int(str(d.get('id'))) == id
                ]  # Need to convert in String and then Int.
            rec['child_rec'] = ch_ids
            rec['groups_id'] = 'group_' + str(random.randrange(1, 10000))
            if group_by:
                rec['group_by_id'] = group_by[0] + '_' + str(
                    grp_records.index(rec))

    return grouped, grp_ids
    def __init__(self, name, model, view, ids=[], domain=[], context={}, **kw):

        self.context = context or {}
        self.domain = copy.deepcopy(domain) or []
        self.group_by_no_leaf = self.context.get('group_by_no_leaf', 0)
        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')

        proxy = rpc.RPCProxy(model)

        # adding the piece of code to set limit as 0 to get rid of pager's negative offset error.
        # Here, we don't change the self.limit as Pager needs -1 to treat Unlimited limit  atribute
        terp_offset, terp_limit = self.offset, self.limit
        if self.limit < 0:
            terp_offset, terp_limit = 0, 0

        custom_search_domain = getattr(cherrypy.request,
                                       'custom_search_domain', [])
        custom_filter_domain = getattr(cherrypy.request,
                                       'custom_filter_domain', [])

        if custom_search_domain:
            self.domain.extend(i for i in custom_search_domain
                               if i not in domain)

        elif custom_filter_domain:
            self.domain.extend(i for i in custom_filter_domain
                               if i not in domain)

        if ids is None and not self.group_by_no_leaf:

            ids = proxy.search(self.domain, terp_offset, terp_limit, 0,
                               self.context)

            if len(ids) < self.limit:
                self.count = len(ids)
            else:
                self.count = proxy.search_count(domain, context)

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

        self.ids = ids

        self.concurrency_info = None

        self.group_by_ctx = kw.get('group_by_ctx', [])

        if not isinstance(self.group_by_ctx, list):
            self.group_by_ctx = [self.group_by_ctx]

        fields = view['fields']
        self.grp_records = []

        self.context.update(rpc.session.context.copy())

        if self.group_by_no_leaf:
            self.limit = -1

        super(ListGroup, self).__init__(name=name,
                                        model=model,
                                        view=view,
                                        ids=self.ids,
                                        domain=self.domain,
                                        context=self.context,
                                        limit=self.limit,
                                        count=self.count,
                                        offset=self.offset,
                                        editable=self.editable,
                                        selectable=self.selectable)

        if self.group_by_ctx:
            self.context['group_by'] = self.group_by_ctx
        else:
            self.group_by_ctx = self.context.get('group_by', [])

        self.group_by_ctx, self.hiddens, self.headers = parse(
            self.group_by_ctx, self.hiddens, self.headers, None,
            self.group_by_ctx)

        self.grp_records = proxy.read_group(
            self.context.get('__domain', []) + (self.domain or []),
            fields.keys(), self.group_by_ctx, 0, False, self.context)

        terp_params = getattr(cherrypy.request, 'terp_params', [])
        if terp_params.sort_key and terp_params.sort_key in self.group_by_ctx and self.group_by_ctx.index(
                terp_params.sort_key) == 0:
            if terp_params.sort_order == 'desc':
                rev = True
            else:
                rev = False
            self.grp_records = sorted(self.grp_records,
                                      key=itemgetter(terp_params.sort_key),
                                      reverse=rev)

        for grp_rec in self.grp_records:
            if not grp_rec.get('__domain'):
                grp_rec['__domain'] = self.context.get(
                    '__domain', []) + (self.domain or [])
            if not grp_rec.get('__context'):
                grp_rec['__context'] = {'group_by': self.group_by_ctx}

        self.grouped, grp_ids = parse_groups(self.group_by_ctx,
                                             self.grp_records, self.headers,
                                             self.ids, model, terp_offset,
                                             terp_limit, self.context,
                                             self.data, self.field_total,
                                             fields)

        if self.pageable:
            self.count = len(self.grouped)
            self.pager = Pager(ids=self.ids,
                               offset=self.offset,
                               limit=self.limit,
                               count=self.count)
            self.pager._name = self.name
Пример #20
0
    def get_fields(self, model, prefix='', name='', field_parent=None, **kw):

        parent_field = kw.get('ids').split(',')[0].split('/')
        if len(parent_field) == 1:
            parent_field = parent_field[0]
        else:
            parent_field = parent_field[-2]

        is_importing = kw.get('is_importing', False)
        import_compat = bool(int(kw.get('import_compat', True)))

        try:
            ctx = ast.literal_eval(kw['context'])
        except:
            ctx = {}

        ctx.update(**rpc.session.context)

        try:
            views = ast.literal_eval(kw['views'])
        except:
            views = {}

        fields = _fields_get_all(model, views, ctx)
        m2ofields = cherrypy.session.get('fld')
        if m2ofields:
            for i in m2ofields:
                if i == parent_field:
                    fields = {}
        else:
            m2ofields = []

        fields.update({
            'id': {
                'string': 'ID'
            },
            '.id': {
                'string': 'Database ID'
            }
        })

        fields_order = fields.keys()
        fields_order.sort(lambda x, y: -cmp(fields[x].get('string', ''),
                                            fields[y].get('string', '')))
        records = []

        for i, field in enumerate(fields_order):
            value = fields[field]
            record = {}

            if import_compat and value.get('readonly', False):
                ok = False
                for sl in value.get('states', {}).values():
                    for s in sl:
                        ok = ok or (s == ('readonly', False))
                if not ok: continue

            id = prefix + (prefix and '/' or '') + field
            nm = name + (name and '/' or '') + value['string']

            if is_importing and (value.get('type') not in ('reference',)) and (not value.get('readonly') \
                        or not dict(value.get('states', {}).get('draft', [('readonly', True)])).get('readonly', True)):

                record.update(id=id,
                              items={'name': nm},
                              action='javascript: void(0)',
                              target=None,
                              icon=None,
                              children=[],
                              required=value.get('required', False))

                records.append(record)

            elif not is_importing:

                record.update(id=id,
                              items={'name': nm},
                              action='javascript: void(0)',
                              target=None,
                              icon=None,
                              children=[])
                records.append(record)

            if len(nm.split('/')) < 3 and value.get('relation', False):

                if import_compat or is_importing:
                    ref = value.pop('relation')
                    proxy = rpc.RPCProxy(ref)
                    cfields = proxy.fields_get(False, rpc.session.context)
                    if (value['type'] == 'many2many') and not is_importing:
                        record['children'] = None
                        record['params'] = {
                            'model': ref,
                            'prefix': id,
                            'name': nm
                        }

                    elif (value['type']
                          == 'many2one') or (value['type'] == 'many2many'
                                             and is_importing):
                        m2ofields.append(field)
                        cfields_order = cfields.keys()
                        cfields_order.sort(
                            lambda x, y: -cmp(cfields[x].get('string', ''),
                                              cfields[y].get('string', '')))
                        children = []
                        for j, fld in enumerate(cfields_order):
                            cid = id + '/' + fld
                            cid = cid.replace(' ', '_')
                            children.append(cid)
                        record['children'] = children or None
                        record['params'] = {
                            'model': ref,
                            'prefix': id,
                            'name': nm
                        }
                        cherrypy.session['fld'] = m2ofields

                    else:
                        cfields_order = cfields.keys()
                        cfields_order.sort(
                            lambda x, y: -cmp(cfields[x].get('string', ''),
                                              cfields[y].get('string', '')))
                        children = []
                        for j, fld in enumerate(cfields_order):
                            cid = id + '/' + fld
                            cid = cid.replace(' ', '_')
                            children.append(cid)
                        record['children'] = children or None
                        record['params'] = {
                            'model': ref,
                            'prefix': id,
                            'name': nm
                        }

                else:
                    ref = value.pop('relation')
                    proxy = rpc.RPCProxy(ref)
                    cfields = proxy.fields_get(False, rpc.session.context)
                    cfields_order = cfields.keys()
                    cfields_order.sort(
                        lambda x, y: -cmp(cfields[x].get('string', ''),
                                          cfields[y].get('string', '')))
                    children = []
                    for j, fld in enumerate(cfields_order):
                        cid = id + '/' + fld
                        cid = cid.replace(' ', '_')
                        children.append(cid)
                    record['children'] = children or None
                    record['params'] = {'model': ref, 'prefix': id, 'name': nm}
                    cherrypy.session['fld'] = []

        records.reverse()
        return dict(records=records)
Пример #21
0
    def filter(self, **kw):
        params, data = TinyDict.split(kw)
        if params.get('_terp_save_current_id'):
            ctx = dict((params.context or {}), **rpc.session.context)
            if params.id:
                rpc.RPCProxy(params.model).write([params.id], data, ctx)
            else:
                id = rpc.RPCProxy(params.model).create(data, ctx)
                params.ids.append(id)
                params.count += 1

        l = params.limit or 50
        o = params.offset or 0
        c = params.count or 0

        id = params.id or False
        ids = params.ids or []
        filter_action = params.filter_action

        if ids and filter_action == 'FIRST':
            o = 0
            id = ids[0]

        if ids and filter_action == 'LAST':
            o = c - c % l
            id = ids[-1]

        if ids and filter_action == 'PREV':
            if id == ids[0]:
                o -= l
            elif id in ids:
                id = ids[ids.index(id) - 1]

        if ids and filter_action == 'NEXT':
            if id == ids[-1]:
                o += l
            elif id in ids:
                id = ids[ids.index(id) + 1]
            elif id is False:
                o = 0
                id = ids[0]

        if filter_action:
            # remember the current page (tab) of notebooks
            cherrypy.session['remember_notebooks'] = True

        if params.offset != o:

            domain = params.domain
            if params.search_domain is not None:
                domain = params.search_domain
                data = params.search_data

            ctx = params.context or {}
            ctx.update(rpc.session.context.copy())
            res = search(params.model,
                         o,
                         l,
                         domain=domain,
                         context=ctx,
                         data=data)

            o = res['offset']
            l = res['limit']
            if not c: c = res['count']

            params.search_domain = res['search_domain']
            params.search_data = res['search_data']

            ids = res['ids']
            id = False

            if ids and filter_action in ('FIRST', 'NEXT'):
                id = ids[0]

            if ids and filter_action in ('LAST', 'PREV'):
                id = ids[-1]

        params.id = id
        params.ids = ids
        params.offset = o
        params.limit = l
        params.count = c

        return self.create(params)
Пример #22
0
 def __init__(self, **kw):
     super(Logs, self).__init__()
     # Server log will display in flash message in form, tree view for any server action like wizard.
     self.logs = rpc.RPCProxy('res.log').get()
Пример #23
0
    def data(self,
             ids,
             model,
             fields,
             field_parent=None,
             icon_name=None,
             domain=[],
             context={},
             sort_by=None,
             sort_order="asc",
             fields_info=None):

        if ids == 'None' or ids == '':
            ids = []

        if isinstance(ids, basestring):
            ids = map(int, ids.split(','))
        elif isinstance(ids, list):
            ids = map(int, ids)

        if isinstance(fields, basestring):
            fields = eval(fields)

        if isinstance(domain, basestring):
            domain = eval(domain)

        if isinstance(context, basestring):
            context = eval(context)

        if isinstance(fields_info, basestring):
            fields_info = simplejson.loads(fields_info)

        if field_parent and field_parent not in fields:
            fields.append(field_parent)

        proxy = rpc.RPCProxy(model)

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

        if icon_name:
            fields.append(icon_name)

        if model == 'ir.ui.menu' and 'action' not in fields:
            fields.append('action')

        result = proxy.read(ids, fields, ctx)

        if sort_by:
            fields_info_type = simplejson.loads(fields_info[sort_by])
            result.sort(lambda a, b: self.sort_callback(
                a, b, sort_by, sort_order, type=fields_info_type['type']))

        # format the data
        for field in fields:
            field_info = simplejson.loads(fields_info[field])
            formatter = FORMATTERS.get(field_info['type'])
            for x in result:
                if x[field] and formatter:
                    x[field] = formatter(x[field], field_info)

        records = []
        for item in result:
            # empty string instead of False or None
            for k, v in item.items():
                if v is None or v is False:
                    item[k] = ''

            id = item.pop('id')
            record = {
                'id':
                id,
                'action':
                url('/openerp/tree/open', model=model, id=id, context=ctx),
                'target':
                None,
                'icon':
                None,
                'children': [],
                'items':
                item
            }

            if icon_name and item.get(icon_name):
                icon = item.pop(icon_name)
                record['icon'] = icons.get_icon(icon)

            if field_parent and field_parent in item:
                record['children'] = item.pop(field_parent) or None

                # For nested menu items, remove void action url
                # to suppress 'No action defined' error.
                if (model == 'ir.ui.menu' and record['children']
                        and not item['action']):
                    record['action'] = None

            records.append(record)

        return {'records': records}
Пример #24
0
def act_window(action, data):
    if not action.get('opened'):
        action.setdefault('target', 'current')
        return act_window_opener(action, data)

    for key in ('res_id', 'res_model', 'view_type', 'view_mode', 'limit',
                'search_view'):
        data[key] = action.get(key, data.get(key))
    if not data.get('search_view') and data.get('search_view_id'):
        data['search_view'] = str(
            rpc.session.execute('object', 'execute', data['res_model'],
                                'fields_view_get', data['search_view_id'],
                                'search', data['context']))
    if data.get('limit'):
        data['limit'] = 20

    if action.get('target') and action['target'] == 'popup' and action.get(
            'res_model') and isinstance(action.get('context'), dict):
        search_view_id = rpc.RPCProxy('ir.ui.view').search(
            [('type', '=', 'search'), ('model', '=', action['res_model'])], 0,
            0, 0, rpc.session.context)
        if search_view_id and action['context'].get('search_view'):
            action['context']['search_view'] = search_view_id[0]

    view_ids = False
    if action.get('views', []):
        if isinstance(action['views'], list):
            view_ids = [x[0] for x in action['views']]
            data['view_mode'] = ",".join([x[1] for x in action['views']])
        else:
            if action.get('view_id'):
                view_ids = [action['view_id'][0]]
    elif action.get('view_id'):
        view_ids = [action['view_id'][0]]
    if not action.get('domain'):
        action['domain'] = '[]'

    ctx = dict(data.get('context', {}),
               active_id=data.get('id', False),
               active_ids=data.get('ids', []),
               active_model=data.get('model', False))

    if action.get('context') and isinstance(action['context'], dict):
        if not action['context'].get('active_ids'):
            action['context']['active_ids'] = ctx['active_ids'] or []

    ctx.update(expr_eval(action.get('context', '{}'), ctx))

    search_view = action.get('search_view_id')
    if search_view:
        if isinstance(search_view, (list, tuple)):
            ctx['search_view'] = search_view[0]
        else:
            ctx['search_view'] = search_view

        # save active_id in session
    rpc.session.active_id = data.get('id')
    domain = expr_eval(action['domain'], ctx)
    if data.get('domain'):
        domain.append(data['domain'])

    if 'menu' in data['res_model'] and action.get('name') == 'Menu':
        return close_popup()

    if action.get('display_menu_tip'):
        display_menu_tip = action.get('help')
    else:
        display_menu_tip = None

    return execute_window(view_ids,
                          data['res_model'],
                          data['res_id'],
                          domain,
                          action['view_type'],
                          ctx,
                          data['view_mode'],
                          name=action.get('name'),
                          target=action.get('target'),
                          limit=data.get('limit'),
                          search_view=data['search_view'],
                          context_menu=data.get('context_menu'),
                          display_menu_tip=display_menu_tip,
                          action_id=action.get('id'))
Пример #25
0
    def index(self, translate='fields', **kw):
        params, data = TinyDict.split(kw)

        ctx = dict((params.context or {}), **rpc.session.context)
        params['context'] = ustr(ctx)

        proxy = rpc.RPCProxy('res.lang')

        lang_ids = proxy.search([('translatable', '=', '1')])
        langs = proxy.read(lang_ids, ['code', 'name'])

        proxy = rpc.RPCProxy(params.model)

        data = []
        view = []

        view_view = cache.fields_view_get(params.model, False, 'form', ctx,
                                          True)

        view_fields = view_view['fields']
        view_relates = view_view.get('toolbar')

        names = view_fields.keys()
        names.sort(lambda x, y: cmp(view_fields[x].get('string', ''),
                                    view_fields[y].get('string', '')))

        if translate == 'fields' and params.id:
            for name in names:
                attrs = view_fields[name]
                if attrs.get('translate'):
                    type = attrs.get('type')
                    value = {}
                    for lang in langs:
                        context = copy.copy(ctx)
                        context['lang'] = adapt_context(lang['code'])

                        val = proxy.read([params.id], [name], context)
                        val = val[0] if isinstance(
                            val, list) and len(val) > 0 else None
                        if val[name] is False:
                            val[name] = ""
                        value[lang['code']] = val[name] if isinstance(val,dict) \
                            and name in val else None

                    data += [(name, value, None, attrs.get('string'), type)]

        if translate == 'labels':
            for name in names:
                attrs = view_fields[name]
                if attrs.get('string'):
                    value = {}
                    for lang in langs:
                        code = lang['code']
                        val = proxy.read_string(False, [code], [name])

                        if name in val[code]:
                            value[code] = val[code][name] or None

                    if value: data += [(name, value, None, None, None)]

        if translate == 'relates' and view_relates:
            for bar, tools in view_relates.items():
                for tool in tools:

                    value = {}
                    for lang in langs:
                        code = lang['code']
                        val = rpc.session.execute('object', 'execute',
                                                  tool['type'], 'read',
                                                  [tool['id']], ['name'],
                                                  {'lang': code})

                        value[code] = val[0]['name'] or None

                    data += [(tool['id'], value, tool['type'], None, None)]

        if translate == 'view':
            for lang in langs:
                code = lang['code']
                view_item_ids = rpc.session.execute(
                    'object', 'execute', 'ir.translation', 'search',
                    [('name', '=', params.model), ('type', '=', 'view'),
                     ('lang', '=', code)])
                view_items = rpc.session.execute('object', 'execute',
                                                 'ir.translation', 'read',
                                                 view_item_ids,
                                                 ['src', 'value'])

                values = []
                for val in view_items:
                    values += [val]

                if values:
                    view += [(code, values)]

        return dict(translate=translate,
                    langs=langs,
                    data=data,
                    view=view,
                    model=params.model,
                    id=params.id,
                    ctx=params.context)
Пример #26
0
def datas_read(ids, model, flds, context=None):
    ctx = dict((context or {}), **rpc.session.context)
    return rpc.RPCProxy(model).export_data(ids, flds, ctx)
    def __init__(self,
                 name,
                 model,
                 view,
                 ids=[],
                 domain=[],
                 parent_group=None,
                 group_level=0,
                 groups=[],
                 context={},
                 **kw):
        self.context = context or {}
        self.domain = domain or []

        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', 50)
        self.count = kw.get('count', 0)

        self.link = kw.get('nolinks')
        self.parent_group = parent_group or None
        self.group_level = group_level or 0
        sort_key = kw.get('sort_key') or ''
        sort_order = kw.get('sort_order') or ''
        proxy = rpc.RPCProxy(model)
        if ids is None:
            if self.limit > 0:
                ids = proxy.search(self.domain, self.offset, self.limit, 0,
                                   rpc.session.context.copy())
            else:
                ids = proxy.search(self.domain, 0, 0, 0,
                                   rpc.session.context.copy())

            if len(ids) < self.limit:
                self.count = len(ids)
            else:
                self.count = proxy.search_count(domain,
                                                rpc.session.context.copy())

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

        self.ids = ids

        self.concurrency_info = None

        self.group_by_ctx = kw.get('group_by_ctx', [])

        if not isinstance(self.group_by_ctx, list):
            self.group_by_ctx = [self.group_by_ctx]

        fields = view['fields']

        self.grp_records = []
        super(MultipleGroup, self).__init__(name=name,
                                            model=model,
                                            view=view,
                                            ids=self.ids,
                                            domain=self.domain,
                                            parent_group=parent_group,
                                            group_level=group_level,
                                            groups=groups,
                                            context=self.context,
                                            limit=self.limit,
                                            count=self.count,
                                            offset=self.offset,
                                            editable=self.editable,
                                            selectable=self.selectable,
                                            sort_order=sort_order,
                                            sort_key=sort_key)

        self.group_by_no_leaf = self.context.get('group_by_no_leaf', 0)

        self.group_by_ctx, self.hiddens, self.headers = parse(
            self.group_by_ctx, self.hiddens, self.headers, self.group_level,
            groups)

        if not len(self.group_by_ctx):
            # Display RAW records (i.e non grouped)
            # NOTE: fetching of ids and data are done by List.__init__() - based on
            #       provided domain, offset, limit, ... params
            self.grp_childs = [{
                'child_rec':
                self.data,
                'groups_id':
                'group_' + str(random.randrange(1, 10000)),
                'group_by_id':
                parent_group,
            }]
            return

        self.grp_records = proxy.read_group(self.context.get('__domain', []),
                                            fields.keys(), self.group_by_ctx,
                                            0, False, self.context)
        for grp_rec in self.grp_records:
            grp_rec['__level'] = self.group_level

        if sort_key and sort_key in self.group_by_ctx and self.group_by_ctx.index(
                sort_key) == 0:
            if sort_order == 'desc':
                rev = True
            else:
                rev = False
            self.grp_records = sorted(self.grp_records,
                                      key=itemgetter(sort_key),
                                      reverse=rev)
        self.grouped, grp_ids = parse_groups(
            self.group_by_ctx, self.grp_records,
            self.headers, self.ids, model, self.offset, self.limit,
            rpc.session.context.copy(), self.data, self.field_total, fields)
Пример #28
0
    def detect_data(self, csvfile, csvsep, csvdel, csvcode, csvskip, **kw):
        params, data = TinyDict.split(kw)

        _fields = {}
        _fields_invert = {}
        error = None

        fields = dict(
            rpc.RPCProxy(params.model).fields_get(False, rpc.session.context))
        fields.update({
            'id': {
                'string': 'ID'
            },
            '.id': {
                'string': 'Database ID'
            }
        })

        def model_populate(fields,
                           prefix_node='',
                           prefix=None,
                           prefix_value='',
                           level=2):
            def str_comp(x, y):
                if x < y: return 1
                elif x > y: return -1
                else: return 0

            fields_order = fields.keys()
            fields_order.sort(lambda x, y: str_comp(
                fields[x].get('string', ''), fields[y].get('string', '')))
            for field in fields_order:
                if (fields[field].get('type','') not in ('reference',))\
                            and (not fields[field].get('readonly')\
                            or not dict(fields[field].get('states', {}).get(
                            'draft', [('readonly', True)])).get('readonly',True)):

                    st_name = prefix_value + fields[field]['string'] or field
                    _fields[prefix_node + field] = st_name
                    _fields_invert[st_name] = prefix_node + field

                    if fields[field].get('type',
                                         '') == 'one2many' and level > 0:
                        fields2 = rpc.session.execute(
                            'object', 'execute', fields[field]['relation'],
                            'fields_get', False, rpc.session.context)
                        model_populate(fields2, prefix_node + field + '/',
                                       None, st_name + '/', level - 1)

                    if fields[field].get('relation', False) and level > 0:
                        model_populate(
                            {
                                '/id': {
                                    'type': 'char',
                                    'string': 'ID'
                                },
                                '.id': {
                                    'type': 'char',
                                    'string': 'Database ID'
                                }
                            }, prefix_node + field, None, st_name + '/',
                            level - 1)

        fields.update({
            'id': {
                'string': 'ID'
            },
            '.id': {
                'string': _('Database ID')
            }
        })
        model_populate(fields)

        try:
            data = csv.reader(csvfile.file,
                              quotechar=str(csvdel),
                              delimiter=str(csvsep))
        except:
            raise common.warning(_('Error opening .CSV file'),
                                 _('Input Error.'))

        records = []
        fields = []
        word = ''
        limit = 3

        try:
            for i, row in enumerate(data):
                records.append(row)
                if i == limit:
                    break

            for line in records:
                for word in line:
                    word = ustr(word.decode(csvcode))
                    if word in _fields:
                        fields.append((word, _fields[word]))
                    elif word in _fields_invert.keys():
                        fields.append((_fields_invert[word], word))
                    else:
                        error = {
                            'message':
                            _("You cannot import the field '%s', because we cannot auto-detect it"
                              % (word, ))
                        }
                break
        except:
            error = {
                'message':
                _('Error processing the first line of the file. Field "%s" is unknown'
                  ) % (word, ),
                'title':
                _('Import Error.')
            }

        kw['fields'] = fields
        if error:
            csvfile.file.seek(0)
            return self.imp(error=dict(error, preview=csvfile.file.read(200)),
                            **kw)
        return self.imp(records=records, **kw)
Пример #29
0
    def eval_domain_filter(self, **kw):

        all_domains = kw.get('all_domains')
        custom_domains = kw.get('custom_domain')

        all_domains = eval(all_domains)

        domains = all_domains.get('domains')
        selection_domain = all_domains.get('selection_domain')
        search_context = all_domains.get('search_context')

        group_by_ctx = kw.get('group_by_ctx', [])
        if isinstance(group_by_ctx, str):
            group_by_ctx = group_by_ctx.split(',')

        if domains:
            domains = eval(domains)

        c = search_context.get('context', {})
        v = search_context.get('value')
        if v and isinstance(v, basestring) and '__' in v:
            value, operator = v.split('__')
            v = int(value)
        ctx = expr_eval(c, {'self':v})

        context = rpc.session.context
        if ctx:
            ctx.update(context)

        domain = []
        check_domain = all_domains.get('check_domain')

        if check_domain and isinstance(check_domain, basestring):
            domain = expr_eval(check_domain, context) or []

        search_data = {}
        model = kw.get('model')
        proxy = rpc.RPCProxy(model)
        res = proxy.fields_get(False, context)
        all_error = []
        fld = {}
        
        if domains:
            for field, value in domains.iteritems():
                
                if '/' in field:
                    fieldname, bound = field.split('/')
                else:
                    fieldname = field
                    bound = ''

                data = {}
                fld['type'] = res[fieldname].get('type')
                if fld['type'] == 'many2many':
                    fld['type'] = 'char'
                fld['value'] = value
                data[field] = fld

                try:
                    frm = TinyForm(**data).to_python()
                except TinyFormError, e:
                    error_field = e.field
                    error = ustr(e)
                    all_error.append(dict(error=error, error_field=error_field))
                    continue

                if bound in ('from', 'to'):
                    if bound == 'from': test = '>='
                    else: test = '<='

                    convert_format = openobject.i18n.format.convert_date_format_in_domain([(fieldname, test, value)], res, context)
                    domain.append(convert_format[0])
                    search_data.setdefault(fieldname, {})[bound] = convert_format[0][2]

                elif isinstance(value, bool) and value:
                    search_data[field] = 1

                elif isinstance(value, int) and not isinstance(value, bool):
                    domain.append((field, '=', value))
                    search_data[field] = value

                elif 'selection_' in value:
                    domain.append((field, '=', value.split('selection_')[1]))
                    search_data[field] = value.split('selection_')[1]

                elif fld['type'] == 'selection':
                    domain.append((field, '=', value))
                    search_data[field] = value

                else:
                    if not 'm2o_' in value:
                        operator = 'ilike'
                        if '__' in value:
                            value, operator = value.split('__')
                            value = int(value)
                        domain.append((field, operator, value))
                        search_data[field] = value
                    else:
                        search_data[field] = value.split('m2o_')[1]
            if all_error:
                return dict(all_error=all_error)
Пример #30
0
    def __init__(self, view, model, res_id=False, domain=[], context={}, action=None, fields=None):
        super(ViewTree, self).__init__(name='view_tree', action=action)

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

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

        if self.field_parent:
            self.domain = domain

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

        proxy = rpc.RPCProxy(self.model)

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

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

        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