def get_tab_domain(self): if not self.notebook: return [] idx = self.notebook.get_current_page() if idx < 0: return [] ctx, domain = self.tab_domain[idx][1] decoder = PYSONDecoder(ctx) return decoder.decode(domain)
def domain(self): group_domain = self.__domain if group_domain and isinstance(group_domain, str): decoder = PYSONDecoder(self.context) group_domain = decoder.decode(group_domain) if self.parent and self.child_name: field = self.parent.group.fields[self.child_name] return [group_domain, field.domain_get(self.parent)] return group_domain
def validate(self, record, softvalidation=False, pre_validate=None): valid = super(DictField, self).validate( record, softvalidation, pre_validate) if self.attrs.get('readonly'): return valid decoder = PYSONDecoder() field_value = self.get_eval(record) domain = [] for key in field_value: if key not in self.keys: continue key_domain = self.keys[key].get('domain') if key_domain: domain.append(decoder.decode(key_domain)) valid_value = eval_domain(domain, field_value) if not valid_value: self.get_state_attrs(record)['invalid'] = 'domain' return valid and valid_value
def _exec_action(action, data=None, context=None): if context is None: context = {} if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return def add_name_suffix(name): if not data.get('ids') or not data.get('model'): return name max_records = 5 rec_names = RPCExecute('model', data['model'], 'read', data['ids'][:max_records], ['rec_name']) name_suffix = _(', ').join([x['rec_name'] for x in rec_names]) if len(data['ids']) > max_records: name_suffix += _(u',\u2026') return _('%s (%s)') % (name, name_suffix) data['action_id'] = action['id'] if action['type'] == 'ir.action.act_window': view_ids = [] view_mode = None if action.get('views', []): view_ids = [x[0] for x in action['views']] view_mode = [x[1] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('model'), 'active_id': data.get('id'), 'active_ids': data.get('ids', []), } ctx.update(rpc.CONTEXT) ctx['_user'] = rpc._USER decoder = PYSONDecoder(ctx) # TODO: comment changes action_ctx = context.copy() action_ctx.update(decoder.decode( action.get('pyson_context') or '{}')) action_ctx.update(ctx) action_ctx.update(data.get('extra_context', {})) action_ctx['context'] = ctx decoder = PYSONDecoder(action_ctx) domain = action['pyson_domain'] order = decoder.decode(action['pyson_order']) search_value = decoder.decode(action['pyson_search_value'] or '[]') tab_domain = [(n, (action_ctx, d), c) for n, d, c in action['domains']] name = action.get('name', '') if action.get('keyword', '') == 'form_relate': name = add_name_suffix(name) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) limit = action.get('limit') if limit is None: limit = CONFIG['client.limit'] Window.create(res_model, view_ids=view_ids, res_id=res_id, domain=domain, context=action_ctx, order=order, mode=view_mode, name=name, limit=limit, search_value=search_value, icon=(action.get('icon.rec_name') or ''), tab_domain=tab_domain, context_model=action['context_model'], context_domain=action.get('context_domain', None)) elif action['type'] == 'ir.action.wizard': name = action.get('name', '') if action.get('keyword', 'form_action') == 'form_action': name = add_name_suffix(name) context = copy.deepcopy(context) context.update(data.get('extra_context', {})) Window.create_wizard(action['wiz_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), name=name, context=context, icon=(action.get('icon.rec_name') or ''), window=action.get('window', False)) elif action['type'] == 'ir.action.report': Action.exec_report(action['report_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), context=context) elif action['type'] == 'ir.action.url': if action['url']: webbrowser.open(action['url'], new=2)
def get_domain(self): if not self.domain or not isinstance(self.domain, basestring): return self.domain decoder = PYSONDecoder(self.context) return decoder.decode(self.domain)
def _exec_action(action, data=None, context=None): from tryton.gui.window import Window if context is None: context = {} else: context = context.copy() if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return context.pop('active_id', None) context.pop('active_ids', None) context.pop('active_model', None) def add_name_suffix(name, context=None): if not data.get('ids') or not data.get('model'): return name max_records = 5 ids = list(filter(lambda id: id >= 0, data['ids']))[:max_records] if not ids: return name rec_names = RPCExecute('model', data['model'], 'read', ids, ['rec_name'], context=context) name_suffix = _(', ').join([x['rec_name'] for x in rec_names]) if len(data['ids']) > len(ids): name_suffix += _(',...') if name_suffix: return _('%s (%s)') % (name, name_suffix) else: return name data['action_id'] = action['id'] if action['type'] == 'ir.action.act_window': view_ids = [] view_mode = None if action.get('views', []): view_ids = [x[0] for x in action['views']] view_mode = [x[1] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('model'), 'active_id': data.get('id'), 'active_ids': data.get('ids') or [], } ctx.update(rpc.CONTEXT) ctx['_user'] = rpc._USER decoder = PYSONDecoder(ctx) action_ctx = context.copy() action_ctx.update( decoder.decode(action.get('pyson_context') or '{}')) ctx.update(action_ctx) ctx['context'] = ctx decoder = PYSONDecoder(ctx) domain = decoder.decode(action['pyson_domain']) order = decoder.decode(action['pyson_order']) search_value = decoder.decode(action['pyson_search_value'] or '[]') tab_domain = [(n, decoder.decode(d), c) for n, d, c in action['domains']] name = action.get('name', '') if action.get('keyword', ''): name = add_name_suffix(name, action_ctx) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) limit = action.get('limit') if limit is None: limit = CONFIG['client.limit'] Window.create(res_model, view_ids=view_ids, res_id=res_id, domain=domain, context=action_ctx, order=order, mode=view_mode, name=name, limit=limit, search_value=search_value, icon=(action.get('icon.rec_name') or ''), tab_domain=tab_domain, context_model=action['context_model'], context_domain=action['context_domain']) elif action['type'] == 'ir.action.wizard': name = action.get('name', '') if action.get('keyword', 'form_action') == 'form_action': name = add_name_suffix(name, context) Window.create_wizard(action['wiz_name'], data, direct_print=action.get( 'direct_print', False), name=name, context=context, icon=(action.get('icon.rec_name') or ''), window=action.get('window', False)) elif action['type'] == 'ir.action.report': Action.exec_report(action['report_name'], data, direct_print=action.get('direct_print', False), context=context) elif action['type'] == 'ir.action.url': if action['url']: webbrowser.open(action['url'], new=2)
def __init__(self, attrs=None, context=None): if context is None: context = {} super(Action, self).__init__() self.name = attrs['name'] try: self.action = RPCExecute('model', 'ir.action.act_window', 'get', self.name) except RPCException: raise view_ids = [] view_mode = None if self.action.get('views', []): view_ids = [x[0] for x in self.action['views']] view_mode = [x[1] for x in self.action['views']] elif self.action.get('view_id', False): view_ids = [self.action['view_id'][0]] self.action.setdefault('pyson_domain', '[]') ctx = {} ctx.update(rpc.CONTEXT) ctx['_user'] = rpc._USER decoder = PYSONDecoder(ctx) action_ctx = context.copy() action_ctx.update( decoder.decode(self.action.get('pyson_context') or '{}')) ctx.update(action_ctx) ctx['context'] = ctx decoder = PYSONDecoder(ctx) self.domain = decoder.decode(self.action['pyson_domain']) order = decoder.decode(self.action['pyson_order']) search_value = decoder.decode(self.action['pyson_search_value'] or '[]') tab_domain = [(n, decoder.decode(d), c) for n, d, c in self.action['domains']] limit = self.action.get('limit') if limit is None: limit = CONFIG['client.limit'] self.context = ctx self.domain = [] self.update_domain([]) self.widget = Gtk.Frame() self.widget.set_border_width(0) vbox = Gtk.VBox(homogeneous=False, spacing=3) self.widget.add(vbox) self.title = Gtk.Label() self.widget.set_label_widget(self.title) self.widget.set_label_align(0.0, 0.5) self.widget.show_all() self.screen = Screen(self.action['res_model'], view_ids=view_ids, domain=self.domain, context=action_ctx, order=order, mode=view_mode, limit=limit, search_value=search_value, tab_domain=tab_domain, context_model=self.action['context_model'], context_domain=self.action['context_domain'], row_activate=self.row_activate) vbox.pack_start(self.screen.widget, expand=True, fill=True, padding=0) self.screen.signal_connect(self, 'record-message', self._active_changed) if attrs.get('string'): self.title.set_text(attrs['string']) else: self.title.set_text(self.action['name']) self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) self.screen.search_filter()
def sig_win_menu(self, prefs=None): from tryton.gui.window.view_form.screen import Screen if not prefs: try: prefs = RPCExecute('model', 'res.user', 'get_preferences', False) except RPCException: return False if self.menu_screen: self.menu_screen.save_tree_state() for child in self.menu.get_children(): self.menu.remove(child) action = PYSONDecoder().decode(prefs['pyson_menu']) view_ids = [] if action.get('views', []): view_ids = [x[0] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] ctx = rpc.CONTEXT.copy() decoder = PYSONDecoder(ctx) action_ctx = decoder.decode(action.get('pyson_context') or '{}') domain = decoder.decode(action['pyson_domain']) screen = Screen(action['res_model'], mode=['tree'], view_ids=view_ids, domain=domain, context=action_ctx, readonly=True, limit=None, row_activate=self.menu_row_activate) # Use alternate view to not show search box screen.screen_container.alternate_view = True screen.switch_view(view_type=screen.current_view.view_type) self.menu.pack_start(screen.screen_container.alternate_viewport, True, True) treeview = screen.current_view.treeview treeview.set_headers_visible(False) # Favorite column column = gtk.TreeViewColumn() column.name = None column._type = None favorite_renderer = CellRendererClickablePixbuf() column.pack_start(favorite_renderer, expand=False) def favorite_setter(column, cell, store, iter_): menu = store.get_value(iter_, 0) favorite = menu.value.get('favorite') if favorite: stock_id = 'tryton-star' elif favorite is False: stock_id = 'tryton-unstar' else: stock_id = '' pixbuf = treeview.render_icon(stock_id=stock_id, size=gtk.ICON_SIZE_MENU, detail=None) cell.set_property('pixbuf', pixbuf) column.set_cell_data_func(favorite_renderer, favorite_setter) def toggle_favorite(renderer, path, treeview): if treeview.props.window: self.toggle_favorite(renderer, path, treeview) favorite_renderer.connect( 'clicked', lambda *a: gobject.idle_add(toggle_favorite, *a), treeview) # Unset fixed height mode to add column treeview.set_fixed_height_mode(False) treeview.set_property('enable-grid-lines', gtk.TREE_VIEW_GRID_LINES_NONE) treeview.append_column(column) screen.search_filter() screen.display(set_cursor=True) self.menu_screen = screen
def _exec_action(action, data=None, context=None): if context is None: context = {} else: context = context.copy() if 'date_format' not in context: context['date_format'] = rpc.CONTEXT.get('locale', {}).get('date', '%x') if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return data['action_id'] = action['id'] if action['type'] == 'ir.action.act_window': view_ids = False view_mode = None if action.get('views', []): view_ids = [x[0] for x in action['views']] view_mode = [x[1] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('model'), 'active_id': data.get('id'), 'active_ids': data.get('ids', []), } ctx.update(rpc.CONTEXT) ctx['_user'] = rpc._USER decoder = PYSONDecoder(ctx) action_ctx = decoder.decode(action.get('pyson_context') or '{}') action_ctx.update(context) action_ctx.update(ctx) action_ctx.update(data.get('extra_context', {})) action_ctx['context'] = ctx decoder = PYSONDecoder(action_ctx) domain = action['pyson_domain'] order = decoder.decode(action['pyson_order']) search_value = decoder.decode(action['pyson_search_value'] or '[]') tab_domain = [(n, (action_ctx, d)) for n, d in action['domains']] name = False if action.get('window_name', True): name = action.get('name', False) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) Window.create(view_ids, res_model, res_id, domain, action_ctx, order, view_mode, name=name, limit=action.get('limit'), search_value=search_value, icon=(action.get('icon.rec_name') or ''), tab_domain=tab_domain, context_model=action['context_model']) elif action['type'] == 'ir.action.wizard': context = copy.deepcopy(context) context.update(data.get('extra_context', {})) Window.create_wizard(action['wiz_name'], data, direct_print=action.get( 'direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), name=action.get('name', False), context=context, icon=(action.get('icon.rec_name') or ''), window=action.get('window', False)) elif action['type'] == 'ir.action.report': Action.exec_report(action['report_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), context=context) elif action['type'] == 'ir.action.url': if action['url']: webbrowser.open(action['url'], new=2)
def _exec_action(action, data=None, context=None): if context is None: context = {} if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return if action['type'] == 'ir.action.act_window': view_ids = False view_mode = None if action.get('views', []): view_ids = [x[0] for x in action['views']] view_mode = [x[1] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('res_model'), 'active_id': data.get('id', False), 'active_ids': data.get('ids', []), } ctx.update(rpc.CONTEXT) eval_ctx = ctx.copy() eval_ctx['_user'] = rpc._USER action_ctx = PYSONDecoder(eval_ctx).decode( action.get('pyson_context') or '{}') ctx.update(action_ctx) ctx.update(context) domain_context = ctx.copy() domain_context['context'] = ctx domain_context['_user'] = rpc._USER domain = PYSONDecoder(domain_context).decode( action['pyson_domain']) search_context = ctx.copy() search_context['context'] = ctx search_context['_user'] = rpc._USER search_value = PYSONDecoder(search_context).decode( action['pyson_search_value'] or '[]') tab_domain_context = ctx.copy() tab_domain_context['context'] = ctx tab_domain_context['_user'] = rpc._USER decoder = PYSONDecoder(tab_domain_context) tab_domain = [(n, decoder.decode(d)) for n, d in action['domains']] name = False if action.get('window_name', True): name = action.get('name', False) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) Window.create(view_ids, res_model, res_id, domain, action_ctx, view_mode, name=name, limit=action.get('limit'), auto_refresh=action.get('auto_refresh'), search_value=search_value, icon=(action.get('icon.rec_name') or ''), tab_domain=tab_domain) elif action['type'] == 'ir.action.wizard': Window.create_wizard(action['wiz_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), name=action.get('name', False), context=context, icon=(action.get('icon.rec_name') or ''), window=action.get('window', False)) elif action['type'] == 'ir.action.report': Action.exec_report(action['report_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), context=context) elif action['type'] == 'ir.action.url': if action['url']: webbrowser.open(action['url'], new=2)
def state_set(self, record): super().state_set(record) if not self.get_visible(): return if CONFIG['client.modepda']: self.hide() return if record: data = { 'model': record.model_name, 'id': record.id, 'ids': [record.id], } context = record.get_context() pyson_ctx = { 'active_model': record.model_name, 'active_id': record.id, 'active_ids': [record.id], } self._current = record.id else: data = {} context = {} pyson_ctx = {} self._current = None pyson_ctx['context'] = context try: self.disconnect_by_func(self.__class__.clicked) except TypeError: pass self.connect('clicked', self.__class__.clicked, [data, context]) action = common.RPCExecute('model', 'ir.action', 'get_action_value', self.action_id, context=context) self.set_label(action['rec_name']) decoder = PYSONDecoder(pyson_ctx) domain = decoder.decode(action['pyson_domain']) if action.get('pyson_search_value'): domain = [domain, decoder.decode(action['pyson_search_value'])] tab_domains = [(n, decoder.decode(d)) for n, d, c in action['domains'] if c] if tab_domains: label = ('%s\n' % action['rec_name']) + '\n'.join( '%s (%%d)' % n for n, _ in tab_domains) else: label = '%s (%%d)' % action['rec_name'] if record and self.action_id in record.links_counts: counter = record.links_counts[self.action_id] self._set_label_counter(label, counter) else: counter = [0] * (len(tab_domains) or 1) if record: record.links_counts[self.action_id] = counter if tab_domains: for i, (_, tab_domain) in enumerate(tab_domains): common.RPCExecute( 'model', action['res_model'], 'search_count', ['AND', domain, tab_domain], context=context, callback=functools.partial(self._set_count, idx=i, current=self._current, counter=counter, label=label)) else: common.RPCExecute('model', action['res_model'], 'search_count', domain, context=context, callback=functools.partial( self._set_count, current=self._current, counter=counter, label=label))
def _exec_action(action, data=None, context=None): if context is None: context = {} else: context = context.copy() if 'date_format' not in context: context['date_format'] = rpc.CONTEXT.get( 'locale', {}).get('date', '%x') if data is None: data = {} else: data = data.copy() if 'type' not in (action or {}): return data['action_id'] = action['id'] if action['type'] == 'ir.action.act_window': view_ids = False view_mode = None if action.get('views', []): view_ids = [x[0] for x in action['views']] view_mode = [x[1] for x in action['views']] elif action.get('view_id', False): view_ids = [action['view_id'][0]] action.setdefault('pyson_domain', '[]') ctx = { 'active_model': data.get('model'), 'active_id': data.get('id'), 'active_ids': data.get('ids', []), } ctx.update(rpc.CONTEXT) ctx['_user'] = rpc._USER decoder = PYSONDecoder(ctx) action_ctx = decoder.decode(action.get('pyson_context') or '{}') action_ctx.update(context) action_ctx.update(ctx) action_ctx.update(data.get('extra_context', {})) action_ctx['context'] = ctx decoder = PYSONDecoder(action_ctx) domain = action['pyson_domain'] order = decoder.decode(action['pyson_order']) search_value = decoder.decode(action['pyson_search_value'] or '[]') tab_domain = [(n, (action_ctx, d)) for n, d in action['domains']] name = False if action.get('window_name', True): name = action.get('name', False) res_model = action.get('res_model', data.get('res_model')) res_id = action.get('res_id', data.get('res_id')) Window.create(view_ids, res_model, res_id, domain, action_ctx, order, view_mode, name=name, limit=action.get('limit'), search_value=search_value, icon=(action.get('icon.rec_name') or ''), tab_domain=tab_domain, context_model=action['context_model']) elif action['type'] == 'ir.action.wizard': context = copy.deepcopy(context) context.update(data.get('extra_context', {})) Window.create_wizard(action['wiz_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), name=action.get('name', False), context=context, icon=(action.get('icon.rec_name') or ''), window=action.get('window', False)) elif action['type'] == 'ir.action.report': Action.exec_report(action['report_name'], data, direct_print=action.get('direct_print', False), email_print=action.get('email_print', False), email=action.get('email'), context=context) elif action['type'] == 'ir.action.url': if action['url']: webbrowser.open(action['url'], new=2)
def display(self, force=False): self.treeview.display_counter += 1 current_record = self.record if (force or not self.treeview.get_model() or self.group != self.treeview.get_model().group): model = AdaptModelGroup(self.group, self.children_field) self.treeview.set_model(model) # __select_changed resets current_record to None self.record = current_record if current_record: selection = self.treeview.get_selection() path = current_record.get_index_path(model.group) selection.select_path(path) # The search column must be set each time the model is changed self.treeview.set_search_column(0) if not current_record: selection = self.treeview.get_selection() selection.unselect_all() self.treeview.queue_draw() if self.editable: self.set_state() self.update_arrow() self.update_sum() # Set column visibility depending on attributes and domain domain = [] if self.screen.domain: domain.append(self.screen.domain) tab_domain = self.screen.screen_container.get_tab_domain() if tab_domain: domain.append(tab_domain) domain = simplify(domain) decoder = PYSONDecoder(self.screen.context) tree_column_optional = self.screen.tree_column_optional.get( self.view_id, {}) for column in self.treeview.get_columns(): name = column.name if not name: continue widget = self.get_column_widget(column) widget.set_editable() if column.name in tree_column_optional: optional = tree_column_optional[column.name] else: optional = bool(int(widget.attrs.get('optional', '0'))) invisible = decoder.decode(widget.attrs.get('tree_invisible', '0')) if invisible or optional: column.set_visible(False) elif name == self.screen.exclude_field: column.set_visible(False) else: inv_domain = domain_inversion(domain, name) if not isinstance(inv_domain, bool): inv_domain = simplify(inv_domain) unique, _, _ = unique_value(inv_domain) column.set_visible(not unique or bool(self.children_field)) if self.children_field: for i, column in enumerate(self.treeview.get_columns()): if self.draggable and not i: continue if column.get_visible(): self.treeview.set_expander_column(column) break