def __init__(self, field_name, model_name, attrs=None): super(Reference, self).__init__(field_name, model_name, attrs=attrs) self.widget_combo = gtk.ComboBoxEntry() child = self.widget_combo.get_child() child.set_editable(False) child.connect('changed', self.sig_changed_combo) self.widget.pack_start(self.widget_combo, expand=False, fill=True) self.widget.pack_start(gtk.Label('-'), expand=False, fill=False) self._selection = {} self._selection2 = {} selection = attrs.get('selection', []) if not isinstance(selection, (list, tuple)): try: selection = RPCExecute('model', self.model_name, selection) except RPCException: selection = [] selection.sort(key=operator.itemgetter(1)) if selection: pop = sorted((len(x) for x in selection), reverse=True) average = sum(pop) / len(pop) deviation = int(math.sqrt(sum((x - average) ** 2 for x in pop) / len(pop))) width = max(next((x for x in pop if x < (deviation * 4)), 10), 10) else: width = 10 child.set_width_chars(width) self.set_popdown(selection) self.widget.set_focus_chain([self.widget_combo, self.wid_text])
def get_selection(self, props): try: selection = RPCExecute('model', self.model_name, props['selection']) except RPCException: selection = [] selection.sort(lambda x, y: cmp(x[1], y[1])) return selection
def init_selection(self): selection = self.attrs.get('selection', [])[:] if not isinstance(selection, (list, tuple)): try: selection = RPCExecute('model', self.model_name, selection) except RPCException: selection = [] self.selection = selection[:] if self.attrs.get('sort', True): selection.sort(key=operator.itemgetter(1)) self.set_popdown(selection)
def __init__(self, field_name, model_name, treeview, attrs=None): super(Reference, self).__init__(field_name, model_name, treeview, attrs=attrs) self._selection = {} selection = attrs.get('selection', []) if not isinstance(selection, (list, tuple)): try: selection = RPCExecute('model', model_name, selection) except RPCException: selection = [] selection.sort(key=operator.itemgetter(1)) for i, j in selection: self._selection[i] = str(j)
def get_selection(self, props): try: change_with = props.get('selection_change_with') if change_with: selection = RPCExecute('model', self.model_name, props['selection'], dict((p, None) for p in change_with)) else: selection = RPCExecute('model', self.model_name, props['selection']) except RPCException: selection = [] selection.sort(lambda x, y: cmp(x[1], y[1])) return selection
def __init__(self, *args): super(Selection, self).__init__(*args) self.renderer = CellRendererCombo() self.renderer.connect('editing-started', self.editing_started) self._last_domain = None self._domain_cache = {} selection = self.attrs.get('selection', [])[:] if not isinstance(selection, (list, tuple)): try: selection = RPCExecute('model', self.model_name, selection) except RPCException: selection = [] self.selection = selection[:] if self.attrs.get('sort', True): selection.sort(key=operator.itemgetter(1)) self.renderer.set_property('model', self.get_model(selection)) self.renderer.set_property('text-column', 0)
def init_selection(self, key=None): if key is None: key = tuple(sorted((k, None) for k in self.attrs.get('selection_change_with') or [])) selection = self.attrs.get('selection', [])[:] if (not isinstance(selection, (list, tuple)) and key not in self._values2selection): try: if key: selection = RPCExecute('model', self.model_name, selection, dict(key)) else: selection = RPCExecute('model', self.model_name, selection) except RPCException: selection = [] self._values2selection[key] = selection elif key in self._values2selection: selection = self._values2selection[key] if self.attrs.get('sort', True): selection.sort(key=operator.itemgetter(1)) self.selection = selection[:]
def update_selection(self, record, field): if not field: return domain = field.domain_get(record) if field.attrs['type'] == 'reference': # The domain on reference field is not only based on the selection # so the selection can not be filtered. domain = [] if 'relation' not in self.attrs: change_with = self.attrs.get('selection_change_with') or [] value = record._get_on_change_args(change_with) del value['id'] self.init_selection(value) self.filter_selection(domain, record, field) else: context = field.context_get(record) domain_cache_key = (freeze_value(domain), freeze_value(context)) if domain_cache_key in self._domain_cache: self.selection = self._domain_cache[domain_cache_key] self._last_domain = (domain, context) if (domain, context) == self._last_domain: return try: result = RPCExecute('model', self.attrs['relation'], 'search_read', domain, 0, None, None, ['rec_name'], context=context) except RPCException: result = False if isinstance(result, list): selection = [(x['id'], x['rec_name']) for x in result] if self.nullable_widget: selection.append((None, '')) self._last_domain = (domain, context) self._domain_cache[domain_cache_key] = selection else: selection = [] self._last_domain = None self.selection = selection[:] self.inactive_selection = []
def save_tree_state(self, store=True): if not CONFIG['client.save_tree_state']: return parent = self.parent.id if self.parent else None timestamp = self.parent._timestamp if self.parent else None for view in self.views: if view.view_type == 'form': for widgets in view.widgets.itervalues(): for widget in widgets: if hasattr(widget, 'screen'): widget.screen.save_tree_state(store) if len(self.views) == 1 and self.current_record: path = self.current_record.id if path < 0: path = -self.current_record.group.index( self.current_record) self.tree_states[parent][view.children_field] = (timestamp, [], [[path]]) elif view.view_type == 'tree': paths = view.get_expanded_paths() selected_paths = view.get_selected_paths() self.tree_states[parent][view.children_field] = ( timestamp, paths, selected_paths) if store and view.attributes.get('tree_state', False): json_domain = self.get_tree_domain(parent) json_paths = json.dumps(paths) json_selected_path = json.dumps(selected_paths) try: RPCExecute('model', 'ir.ui.view_tree_state', 'set', self.model_name, json_domain, view.children_field, json_paths, json_selected_path, process_exception=False) except (TrytonServerError, TrytonServerUnavailable): logging.getLogger(__name__).warn( _('Unable to set view tree state'))
def toggle_favorite(self, renderer, path, treeview): store = treeview.get_model() iter_ = store.get_iter(path) menu = store.get_value(iter_, 0) favorite = menu.value.get('favorite') if favorite: value = False method = 'unset' elif favorite is False: value = True method = 'set' else: return try: RPCExecute('model', self.menu_screen.model_name + '.favorite', method, menu.id) except RPCException: return menu.value['favorite'] = value store.row_changed(path, iter_) self.favorite_unset()
def get_data(self, record): if not isinstance(record.value.get(self.name), (str, bytes, _FileCache)): if record.id < 0: return b'' context = record.get_context() try: values, = RPCExecute('model', record.model_name, 'read', [record.id], [self.name], context=context) except RPCException: return b'' _, filename = tempfile.mkstemp(prefix='tryton_') data = values[self.name] or b'' if isinstance(data, str): data = data.encode('utf-8') with open(filename, 'wb') as fp: fp.write(data) self.set(record, _FileCache(filename)) return self.get(record)
def default_get(self, rec_name=None): vals = None if len(self.group.fields): context = self.get_context() context.setdefault('default_rec_name', rec_name) try: vals = RPCExecute('model', self.model_name, 'default_get', list(self.group.fields.keys()), context=context) except RPCException: return if (self.parent and self.parent_name in self.group.fields): parent_field = self.group.fields[self.parent_name] if isinstance(parent_field, fields.ReferenceField): vals[self.parent_name] = ( self.parent.model_name, self.parent.id) elif (self.group.fields[self.parent_name].attrs['relation'] == self.group.parent.model_name): vals[self.parent_name] = self.parent.id self.set_default(vals) return vals
def response(self, win, response): if response == gtk.RESPONSE_OK: for code, widget in self.widgets.iteritems(): widget, editing, fuzzy = widget if not editing.get_active(): continue value = self.widget.translate_widget_get(widget) context = dict( language=code, fuzzy_translation=False, ) try: RPCExecute('model', self.widget.record.model_name, 'write', [self.widget.record.id], { self.widget.field_name: value, }, context=context) except RPCException: pass self.widget.record.cancel() self.widget.view.display() self.destroy()
def import_csv(self, csv_data, fields, model): # TODO: make it works with references fname = csv_data['fname'] data = list(csv.reader(open(fname, 'rb'), quotechar=csv_data['del'], delimiter=csv_data['sep']))[int(csv_data['skip']):] datas = [] for line in data: if not line: continue datas.append([x.decode(csv_data['combo']).encode('utf-8') for x in line]) try: count = RPCExecute('model', model, 'import_data', fields, datas, context=self.context) except RPCException: return if count == 1: common.message(_('%d record imported!') % count) else: common.message(_('%d records imported!') % count)
def remove_predef(self, widget): sel = self.pref_export.get_selection().get_selected() if sel is None: return None (model, i) = sel if not i: return None export_id = model.get_value(i, 0) try: RPCExecute('model', 'ir.export', 'delete', [export_id], context=self.context) except RPCException: return clear_cache('model.%s.view_toolbar_get' % self.model) for i in range(len(self.predef_model)): if self.predef_model[i][0] == export_id: del self.predef_model[i] break self.pref_export.set_model(self.predef_model)
def count_tab_domain(self): def set_tab_counter(count, idx): try: count = count() except RPCException: count = None self.screen_container.set_tab_counter(count, idx) screen_domain = self.search_domain(self.screen_container.get_text()) for idx, (name, domain, count) in enumerate(self.screen_container.tab_domain): if not count: continue domain = ['AND', domain, screen_domain] set_tab_counter(lambda: None, idx) RPCExecute('model', self.model_name, 'search_count', domain, context=self.context, callback=functools.partial(set_tab_counter, idx=idx))
def exec_report(name, data, direct_print=False, context=None): if context is None: context = {} else: context = context.copy() context['direct_print'] = direct_print ids = data.get('ids', []) def callback(result): try: result = result() except RPCException: return type, data, print_p, name = result if not print_p and direct_print: print_p = True fp_name = file_write((name, type), data) file_open(fp_name, type, print_p=print_p) RPCExecute( 'report', name, 'execute', ids, data, context=context, callback=callback)
def _update_completion(self, text): if not self.props.window: return False if text != self.get_text(): return False model = self._completion.get_model() if not text: model.clear() model.text = text return False if getattr(model, 'text', None) == text: return False def callback(results): try: results = results() except (TrytonError, TrytonServerError): logger.warning(_("Unable to complete email entry"), exc_info=True) results = [] if text != self.get_text(): return False model.clear() for ratio, address, addresses in results: model.append([address, addresses]) model.text = text # Force display of popup self.emit('changed') try: RPCExecute('model', 'ir.email', 'complete', text, CONFIG['client.limit'], process_exception=False, callback=callback) except Exception: logger.warning(_("Unable to complete email entry"), exc_info=True) return False
def response(self, dialog, response): if response == gtk.RESPONSE_OK: fields = [] fields2 = [] iter = self.model2.get_iter_root() while iter: fields.append(self.model2.get_value(iter, 1)) fields2.append(self.model2.get_value(iter, 0)) iter = self.model2.iter_next(iter) action = self.wid_action.get_active() self.destroy() try: result = RPCExecute('model', self.model, 'export_data', self.ids, fields, context=self.context) except RPCException: result = [] if action == 0: fileno, fname = tempfile.mkstemp('.csv', 'tryton_') self.export_csv(fname, fields2, result, self.wid_write_field_names.get_active(), popup=False) os.close(fileno) common.file_open(fname, 'csv') else: fname = common.file_selection( _('Save As...'), action=gtk.FILE_CHOOSER_ACTION_SAVE) if fname: self.export_csv(fname, fields2, result, self.wid_write_field_names.get_active()) return True else: self.destroy() return False
def _set_value(self, record, value, default=False): self._set_default_value(record) group = record.value[self.name] if not value or (len(value) and isinstance(value[0], (int, long))): mode = 'list ids' else: mode = 'list values' if mode == 'list values' and len(value): context = self.context_get(record) field_names = set(f for v in value for f in v if f not in group.fields and '.' not in f) if field_names: try: fields = RPCExecute('model', self.attrs['relation'], 'fields_get', list(field_names), context=context) except RPCException: return group.load_fields(fields) if mode == 'list ids': for old_record in group: if old_record.id not in value: group.remove(old_record, remove=True, signal=False) group.load(value) else: for vals in value: new_record = record.value[self.name].new(default=False) if default: # Don't validate as parent will validate new_record.set_default(vals, signal=False, validate=False) group.add(new_record, signal=False) else: new_record.set(vals, signal=False) group.append(new_record) # Trigger signal only once with the last record new_record.signal('record-changed')
def update(search_text, domain): if not entry.props.window: return False if search_text != entry.get_text().decode('utf-8'): return False completion_model = entry.get_completion().get_model() if not search_text or not model: completion_model.clear() completion_model.search_text = search_text return False if getattr(completion_model, 'search_text', None) == search_text: return False if domain is None: domain = field.domain_get(record) context = field.get_search_context(record) domain = [('rec_name', 'ilike', '%' + search_text + '%'), domain] order = field.get_search_order(record) def callback(results): try: results = results() except (TrytonError, TrytonServerError): results = [] if search_text != entry.get_text().decode('utf-8'): return False completion_model.clear() for result in results: completion_model.append([result['rec_name'], result['id']]) completion_model.search_text = search_text # Force display of popup entry.emit('changed') try: RPCExecute('model', model, 'search_read', domain, 0, CONFIG['client.limit'], order, ['rec_name'], context=context, process_exception=False, callback=callback) except Exception: logging.warn( _("Unable to search for completion of %s") % model, exc_info=True) return False
def do_export(self, widget, export): if not self.modified_save(): return ids = [r.id for r in self.screen.selected_records] fields = [f['name'] for f in export['export_fields.']] data = RPCExecute('model', self.model, 'export_data', ids, fields, context=self.screen.context) delimiter = ',' if os.name == 'nt' and ',' == locale.localeconv()['decimal_point']: delimiter = ';' fileno, fname = tempfile.mkstemp('.csv', common.slugify(export['name']) + '_') with open(fname, 'w') as fp: writer = csv.writer(fp, delimiter=delimiter) writer.writerow(fields) writer.writerows(data) os.close(fileno) common.file_open(fname, 'csv')
def add_new_keys(self, ids): context = self.field.get_context(self.record) self.send_modified() try: new_fields = RPCExecute('model', self.schema_model, 'get_keys', ids, context=context) except RPCException: new_fields = [] focus = False for new_field in new_fields: if new_field['name'] not in self.fields: self.keys[new_field['name']] = new_field self.add_line(new_field['name']) if not focus: # Use idle add because it can be called from the callback # of WinSearch while the popup is still there gobject.idle_add( self.fields[new_field['name']].widget.grab_focus) focus = True
def exec_keyword(keyword, data=None, context=None, warning=True, alwaysask=False): actions = [] model_id = data.get('id', False) try: actions = RPCExecute('model', 'ir.action.keyword', 'get_keyword', keyword, (data['model'], model_id)) except RPCException: return False keyact = {} for action in actions: keyact[action['name'].replace('_', '')] = action res = selection(_('Select your action'), keyact, alwaysask=alwaysask) if res: (name, action) = res Action._exec_action(action, data, context=context) return (name, action) elif not len(keyact) and warning: message(_('No action defined.')) return False
def __init__(self, model, view_id, context=None, name=False): super(Board, self).__init__() try: view, = RPCExecute('model', 'ir.ui.view', 'read', [view_id], ['arch'], context=context) except RPCException: raise self.board = ViewBoard(view['arch'], context=context) self.model = model self.view_id = view_id self.context = context self.dialogs = [] if not name: self.name = self.board.name else: self.name = name self.create_tabcontent()
def sig_logs(self, widget=None): current_record = self.screen.current_record if not current_record or current_record.id < 0: self.message_info(_('You have to select one record.'), Gtk.MessageType.INFO) return False fields = [ ('id', _('ID:')), ('create_uid.rec_name', _('Created by:')), ('create_date', _('Created at:')), ('write_uid.rec_name', _('Edited by:')), ('write_date', _('Edited at:')), ] try: data = RPCExecute('model', self.model, 'read', [current_record.id], [x[0] for x in fields], context=self.screen.context)[0] except RPCException: return date_format = self.screen.context.get('date_format', '%x') datetime_format = date_format + ' %H:%M:%S.%f' message_str = '' for (key, label) in fields: value = data keys = key.split('.') name = keys.pop(-1) for key in keys: value = value.get(key + '.', {}) value = (value or {}).get(name, '/') if isinstance(value, datetime.datetime): value = timezoned_date(value).strftime(datetime_format) message_str += '%s %s\n' % (label, value) message_str += _('Model:') + ' ' + self.model message(message_str) return True
def digits(self, record, factor=1): digits = record.expr_eval(self.attrs.get('digits')) if isinstance(digits, str): if digits not in record.group.fields: return digits_field = record.group.fields[digits] digits_name = digits_field.attrs.get('relation') digits_id = digits_field.get(record) if digits_name and digits_id is not None and digits_id >= 0: try: digits = RPCExecute('model', digits_name, 'get_digits', digits_id) except RPCException: logger.warn("Fail to fetch digits for %s,%s", digits_name, digits_id) return else: return if not digits or any(d is None for d in digits): return shift = int(round(math.log(abs(factor), 10))) return (digits[0] + shift, digits[1] - shift)
def import_csv(self, fname, fields): # TODO: make it works with references skip = self.csv_skip.get_value_as_int() encoding = self.get_encoding() locale_format = self.csv_locale.get_active() reader = csv.reader(open(fname, 'r', encoding=encoding), quotechar=self.get_quotechar(), delimiter=self.get_delimiter()) data = [] for i, line in enumerate(reader): if i < skip or not line: continue row = [] for field, val in zip(fields, line): if locale_format and val: type_ = self.fields_data[field]['type'] if type_ in ['integer', 'biginteger']: val = locale.atoi(val) elif type_ == 'float': val = locale.atof(val) elif type_ == 'numeric': val = Decimal(locale.delocalize(val)) elif type_ in ['date', 'datetime']: val = date_parse(val, common.date_format()) row.append(val) data.append(row) try: count = RPCExecute('model', self.model, 'import_data', fields, data, context=self.context) except RPCException: return if count == 1: common.message(_('%d record imported.') % count) else: common.message(_('%d records imported.') % count)
def _sig_add(self, *args): from tryton.gui.window.win_search import WinSearch domain = self.domain[:] model_name = self.screen.model_name try: if self.wid_text.get_text(): dom = [('rec_name', 'ilike', '%' + self.wid_text.get_text() + '%'), domain] else: dom = domain ids = RPCExecute('model', model_name, 'search', dom, 0, CONFIG['client.limit'], None, context=self.context) except RPCException: return False def callback(result): if result: ids = [x[0] for x in result] self.screen.load(ids, modified=True) self.screen.display(res_id=ids[0]) self.screen.set_cursor() self.wid_text.set_text('') if len(ids) != 1: WinSearch(model_name, callback, sel_multi=True, ids=ids, context=self.context, domain=domain) else: callback([(i, None) for i in ids])
def favorite_set(self, *args): if self.menu_favorite.get_children(): return True def _action_favorite(widget, id_): event = Gtk.get_current_event() allow_similar = (event.state & Gdk.ModifierType.MOD1_MASK or event.state & Gdk.ModifierType.SHIFT_MASK) with Window(allow_similar=allow_similar): # ids is not defined to prevent to add suffix Action.exec_keyword('tree_open', { 'model': self.menu_screen.model_name, 'id': id_, }) def _manage_favorites(widget): Window.create(self.menu_screen.model_name + '.favorite', mode=['tree', 'form'], name=_("Favorites")) try: favorites = RPCExecute('model', self.menu_screen.model_name + '.favorite', 'get', process_exception=False) except Exception: return False for id_, name, icon in favorites: menuitem = Gtk.MenuItem(label=name) menuitem.connect('activate', _action_favorite, id_) self.menu_favorite.add(menuitem) self.menu_favorite.add(Gtk.SeparatorMenuItem()) manage_favorites = Gtk.MenuItem(label=_("Manage..."), use_underline=True) manage_favorites.connect('activate', _manage_favorites) self.menu_favorite.add(manage_favorites) self.menu_favorite.show_all() return True
def response(self, dialog, response): if response == Gtk.ResponseType.OK: if not self.validate(): return to = self.to.get_text() cc = self.cc.get_text() bcc = self.bcc.get_text() subject = self.subject.get_text() body = get_content(self.body) files = list(self.get_files()) reports = [ id_ for id_, check in self.print_actions.items() if check.get_active() ] attachments = self.get_attachments() try: RPCExecute('model', 'ir.email', 'send', to, cc, bcc, subject, body, files, [self.record.model_name, self.record.id], reports, attachments) except RPCException: return self.destroy()
def delete(self, records): if not records: return root_group = self.root_group assert all(r.model_name == self.model_name for r in records) assert all(r.group.root_group == root_group for r in records) records = [r for r in records if r.id >= 0] ctx = self.context ctx['_timestamp'] = {} for rec in records: ctx['_timestamp'].update(rec.get_timestamp()) record_ids = set(r.id for r in records) reload_ids = set(root_group.on_write_ids(list(record_ids))) reload_ids -= record_ids reload_ids = list(reload_ids) try: RPCExecute('model', self.model_name, 'delete', list(record_ids), context=ctx) except RPCException: return False if reload_ids: root_group.reload(reload_ids) return True
def get_symbol(self, record, symbol): if record and symbol in record.group.fields: value = self.get(record) or 0 sign = 1 if value < 0: sign = -1 elif value == 0: sign = 0 symbol_field = record.group.fields[symbol] symbol_name = symbol_field.attrs.get('relation') symbol_id = symbol_field.get(record) if symbol_name and symbol_id is not None and symbol_id >= 0: try: return RPCExecute('model', symbol_name, 'get_symbol', symbol_id, sign, context=record.get_context()) except RPCException: logger.warn("Fail to fetch symbol for %s,%s", symbol_name, symbol_id) return '', 1
def __init__(self, model, name='', **attributes): super(Board, self).__init__(**attributes) context = attributes.get('context') self.view_ids = attributes.get('view_ids') try: view, = RPCExecute('model', 'ir.ui.view', 'read', self.view_ids, ['arch'], context=context) except RPCException: raise xml_dom = xml.dom.minidom.parseString(view['arch']) root, = xml_dom.childNodes self.board = ViewBoard(root, context=context) self.model = model self.dialogs = [] if not name: name = MODELNAME.get(model) self.name = name self.create_tabcontent() self.board.reload()
def button(self, button): 'Execute button on the current record' if button.get('confirm', False) and not sur(button['confirm']): return record = self.current_record if not record.save(force_reload=False): return context = record.context_get() try: action_id = RPCExecute('model', self.model_name, button['name'], [record.id], context=context) except RPCException: action_id = None if action_id: Action.execute(action_id, { 'model': self.model_name, 'id': record.id, 'ids': [record.id], }, context=context) self.reload([record.id], written=True)
def import_csv(self, fname, fields): # TODO: make it works with references skip = self.csv_skip.get_value_as_int() encoding = self.get_encoding() reader = csv.reader( open(fname, 'rb'), quotechar=self.get_quotechar(), delimiter=self.get_delimiter()) data = [] for i, line in enumerate(reader): if i < skip or not line: continue data.append([x.decode(encoding).encode('utf-8') for x in line]) try: count = RPCExecute( 'model', self.model, 'import_data', fields, data, context=self.context) except RPCException: return if count == 1: common.message(_('%d record imported.') % count) else: common.message(_('%d records imported.') % count)
def execute(act_id, data, action_type=None, context=None, keyword=False): # Must be executed synchronously to avoid double execution # on double click. if not action_type: action, = RPCExecute('model', 'ir.action', 'read', [act_id], ['type'], context=context) action_type = action['type'] action, = RPCExecute('model', action_type, 'search_read', [('action', '=', act_id)], 0, 1, None, None, context=context) if keyword: keywords = { 'ir.action.report': 'form_report', 'ir.action.wizard': 'form_action', 'ir.action.act_window': 'form_relate', } action.setdefault('keyword', keywords.get(action_type, '')) Action._exec_action(action, data, context=context)
def __init__(self, attrs=None, context=None): super(Action, self).__init__() self.act_id = int(attrs['name']) self.context = context or {} try: self.action = RPCExecute('model', 'ir.action.act_window', 'read', self.act_id, False) except RPCException: raise view_ids = None self.action['view_mode'] = None if self.action.get('views', []): view_ids = [x[0] for x in self.action['views']] self.action['view_mode'] = [x[1] for x in self.action['views']] elif self.action.get('view_id', False): view_ids = [self.action['view_id'][0]] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] self.action.setdefault('pyson_domain', '[]') self.context.update(rpc.CONTEXT) self.context['_user'] = rpc._USER self.context.update(PYSONDecoder(self.context).decode( self.action.get('pyson_context', '{}'))) eval_ctx = self.context.copy() self.context.update(PYSONDecoder(eval_ctx).decode( self.action.get('pyson_context', '{}'))) self.domain = [] self.update_domain([]) search_context = self.context.copy() search_context['context'] = self.context search_context['_user'] = rpc._USER search_value = PYSONDecoder(search_context).decode( self.action['pyson_search_value'] or '{}') 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'], mode=self.action['view_mode'], context=self.context, view_ids=view_ids, domain=self.domain, search_value=search_value, row_activate=self.row_activate) vbox.pack_start(self.screen.widget, expand=True, fill=True) name = self.screen.current_view.title self.screen.signal_connect(self, 'record-message', self._active_changed) if attrs.get('string'): self.title.set_text(attrs['string']) elif self.action.get('window_name'): self.title.set_text(self.action['name']) else: self.title.set_text(name) self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) self.screen.search_filter()
class Action(SignalEvent): def __init__(self, attrs=None, context=None): super(Action, self).__init__() self.act_id = int(attrs['name']) self.context = context or {} try: self.action = RPCExecute('model', 'ir.action.act_window', 'read', self.act_id, False) except RPCException: raise view_ids = None self.action['view_mode'] = None if self.action.get('views', []): view_ids = [x[0] for x in self.action['views']] self.action['view_mode'] = [x[1] for x in self.action['views']] elif self.action.get('view_id', False): view_ids = [self.action['view_id'][0]] if 'view_mode' in attrs: self.action['view_mode'] = attrs['view_mode'] self.action.setdefault('pyson_domain', '[]') self.context.update(rpc.CONTEXT) self.context['_user'] = rpc._USER self.context.update(PYSONDecoder(self.context).decode( self.action.get('pyson_context', '{}'))) eval_ctx = self.context.copy() self.context.update(PYSONDecoder(eval_ctx).decode( self.action.get('pyson_context', '{}'))) self.domain = [] self.update_domain([]) search_context = self.context.copy() search_context['context'] = self.context search_context['_user'] = rpc._USER search_value = PYSONDecoder(search_context).decode( self.action['pyson_search_value'] or '{}') 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'], mode=self.action['view_mode'], context=self.context, view_ids=view_ids, domain=self.domain, search_value=search_value, row_activate=self.row_activate) vbox.pack_start(self.screen.widget, expand=True, fill=True) name = self.screen.current_view.title self.screen.signal_connect(self, 'record-message', self._active_changed) if attrs.get('string'): self.title.set_text(attrs['string']) elif self.action.get('window_name'): self.title.set_text(self.action['name']) else: self.title.set_text(name) self.widget.set_size_request(int(attrs.get('width', -1)), int(attrs.get('height', -1))) self.screen.search_filter() def row_activate(self): if not self.screen.current_record: return def callback(result): if result: self.screen.current_record.save() else: self.screen.current_record.cancel() WinForm(self.screen, callback) def set_value(self, mode, model_field): self.screen.current_view.set_value() return True def display(self): self.screen.search_filter(self.screen.screen_container.get_text()) def _active_changed(self, *args): self.signal('active-changed') def _get_active(self): if self.screen and self.screen.current_record: return common.EvalEnvironment(self.screen.current_record, False) active = property(_get_active) def update_domain(self, actions): domain_ctx = self.context.copy() domain_ctx['context'] = domain_ctx domain_ctx['_user'] = rpc._USER for action in actions: if action.active: domain_ctx['_active_%s' % action.act_id] = action.active new_domain = PYSONDecoder(domain_ctx).decode( self.action['pyson_domain']) if self.domain == new_domain: return del self.domain[:] self.domain.extend(new_domain) if hasattr(self, 'screen'): # Catch early update self.display()