Example #1
0
    def set_on_change(self, record, value):
        record.modified_fields.setdefault(self.name)
        self._set_default_value(record)
        if isinstance(value, (list, tuple)):
            self._set_value(record, value, modified=True)
            return

        if value and (value.get('add') or value.get('update')):
            context = self.get_context(record)
            fields = record.value[self.name].fields
            values = chain(value.get('update', []),
                           (d for _, d in value.get('add', [])))
            field_names = set(f for v in values for f in v
                              if f not in fields and f != 'id')
            if field_names:
                try:
                    fields = RPCExecute('model',
                                        self.attrs['relation'],
                                        'fields_get',
                                        list(field_names),
                                        context=context)
                except RPCException:
                    return
            else:
                fields = {}

        to_remove = []
        for record2 in record.value[self.name]:
            if not record2.id:
                to_remove.append(record2)
        if value and value.get('remove'):
            for record_id in value['remove']:
                record2 = record.value[self.name].get(record_id)
                if record2 is not None:
                    to_remove.append(record2)
        for record2 in to_remove:
            record.value[self.name].remove(record2,
                                           signal=False,
                                           force_remove=False)

        if value and (value.get('add') or value.get('update', [])):
            record.value[self.name].add_fields(fields, signal=False)
            for index, vals in value.get('add', []):
                new_record = record.value[self.name].new(default=False)
                record.value[self.name].add(new_record, index, signal=False)
                new_record.set_on_change(vals)

            for vals in value.get('update', []):
                if 'id' not in vals:
                    continue
                record2 = record.value[self.name].get(vals['id'])
                if record2 is not None:
                    record2.set_on_change(vals)
Example #2
0
 def response(self, win, response_id):
     if response_id == Gtk.ResponseType.OK:
         if self.screen.current_record.validate():
             vals = copy.copy(self.screen.get())
             try:
                 RPCExecute('model', 'res.user', 'set_preferences', vals)
             except RPCException:
                 return
             rpc.context_reset()
     self.parent.present()
     self.destroy()
     self.callback()
Example #3
0
 def copy(self):
     ids = [r.id for r in self.selected_records]
     try:
         new_ids = RPCExecute('model',
                              self.model_name,
                              'copy',
                              ids, {},
                              context=self.context)
     except RPCException:
         return False
     self.load(new_ids)
     return True
Example #4
0
 def add_view_id(self, view_id, view_type):
     if view_id and str(view_id) in self.views_preload:
         view = self.views_preload[str(view_id)]
     elif not view_id and view_type in self.views_preload:
         view = self.views_preload[view_type]
     else:
         try:
             view = RPCExecute('model', self.model_name, 'fields_view_get',
                 view_id, view_type, context=self.context)
         except RPCException:
             return
     return self.add_view(view)
Example #5
0
 def do_autocomplete(self, fieldname):
     self.autocompletion[fieldname] = []
     autocomplete = self.group.fields[fieldname].attrs['autocomplete']
     args = self._get_on_change_args(autocomplete)
     try:
         res = RPCExecute(
             'model', self.model_name,
             'autocomplete_' + fieldname, args, context=self.get_context())
     except RPCException:
         # ensure res is a list
         res = []
     self.autocompletion[fieldname] = res
Example #6
0
 def end(self, callback=None):
     def end_callback(action):
         self.destroy(action=action())
         if callback:
             callback()
     try:
         RPCExecute('wizard', self.action, 'delete', self.session_id,
             process_exception=False, callback=end_callback)
     except Exception:
         logger.warn(
             _("Unable to delete wizard %s") % self.session_id,
             exc_info=True)
Example #7
0
 def set_tree_state(self):
     view = self.current_view
     if view.view_type not in ('tree', 'form'):
         return
     if id(view) in self.tree_states_done:
         return
     if view.view_type == 'form' and self.tree_states_done:
         return
     parent = self.parent.id if self.parent else None
     expanded_nodes, selected_nodes = [], []
     timestamp = self.parent._timestamp if self.parent else None
     state = self.tree_states[parent][view.children_field]
     if state:
         state_timestamp, expanded_nodes, selected_nodes = state
         if (timestamp != state_timestamp and view.view_type != 'form'):
             state = None
     if state is None and CONFIG['client.save_tree_state'] and (
             view.view_type != 'tree' or not view.always_expand):
         json_domain = self.get_tree_domain(parent)
         try:
             expanded_nodes, selected_nodes = RPCExecute(
                 'model', 'ir.ui.view_tree_state', 'get', self.model_name,
                 json_domain, view.children_field)
             expanded_nodes = json.loads(expanded_nodes)
             selected_nodes = json.loads(selected_nodes)
         except RPCException:
             logging.getLogger(__name__).warn(
                 _('Unable to get view tree state'))
         self.tree_states[parent][view.children_field] = (timestamp,
                                                          expanded_nodes,
                                                          selected_nodes)
     if view.view_type == 'tree':
         view.expand_nodes(expanded_nodes)
         view.select_nodes(selected_nodes)
     else:
         if selected_nodes:
             record = None
             for node in selected_nodes[0]:
                 new_record = self.group.get(node)
                 if node < 0 and -node < len(self.group):
                     # Negative id is the index of the new record
                     new_record = self.group[-node]
                 if not new_record:
                     break
                 else:
                     record = new_record
             if record and record != self.current_record:
                 self.current_record = record
                 # Force a display of the view to synchronize the
                 # widgets with the new record
                 view.display()
     self.tree_states_done.add(id(view))
Example #8
0
    def update_selection(self, record, field):
        if not field:
            return

        domain = field.domain_get(record)
        if 'relation' not in self.attrs:
            change_with = self.attrs.get('selection_change_with') or []
            value = record._get_on_change_args(change_with)
            value.pop('id', None)
            self.init_selection(value)
            self.filter_selection(domain, record, field)
        else:
            context = field.get_context(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
            fields = ['rec_name']
            help_field = self.attrs.get('help_field')
            if help_field:
                fields.append(help_field)
            try:
                result = RPCExecute('model',
                                    self.attrs['relation'],
                                    'search_read',
                                    domain,
                                    0,
                                    None,
                                    None,
                                    fields,
                                    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, ''))
                if help_field:
                    help_ = {x['id']: x[help_field] for x in result}
                else:
                    help_ = {}
                self._last_domain = (domain, context)
                self._domain_cache[domain_cache_key] = selection
            else:
                selection = []
                help_ = {}
                self._last_domain = None
            self.selection = selection[:]
            self.help = help_
            self.inactive_selection = []
Example #9
0
 def fill_predefwin(self):
     try:
         export_ids = RPCExecute('model',
                                 'ir.export',
                                 'search', [('resource', '=', self.model)],
                                 0,
                                 None,
                                 None,
                                 context=self.context)
     except RPCException:
         return
     try:
         exports = RPCExecute('model',
                              'ir.export',
                              'read',
                              export_ids,
                              None,
                              context=self.context)
     except RPCException:
         return
     try:
         lines = RPCExecute('model',
                            'ir.export.line',
                            'read',
                            sum((list(x['export_fields']) for x in exports),
                                []),
                            None,
                            context=self.context)
     except RPCException:
         return
     id2lines = {}
     for line in lines:
         id2lines.setdefault(line['export'], []).append(line)
     for export in exports:
         self.predef_model.append(
             (export['id'],
              [x['name']
               for x in id2lines.get(export['id'], [])], export['name']))
     self.pref_export.set_model(self.predef_model)
Example #10
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 self.attrs.get('selection_change_with'):
                 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[:]
     self.inactive_selection = []
Example #11
0
 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,
                          'fetch_action',
                          act_id,
                          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)
Example #12
0
 def get_button_clicks(self, name):
     if self.id < 0:
         return
     clicks = self.button_clicks.get(name)
     if clicks is not None:
         return clicks
     try:
         clicks = RPCExecute('model', 'ir.model.button.click', 'get_click',
                             self.model_name, name, self.id)
         self.button_clicks[name] = clicks
     except RPCException:
         return
     return clicks
Example #13
0
 def pre_validate(self):
     if not self.modified_fields:
         return True
     values = self._get_on_change_args(self.modified_fields)
     try:
         RPCExecute('model',
                    self.model_name,
                    'pre_validate',
                    values,
                    context=self.get_context())
     except RPCException:
         return False
     return True
Example #14
0
 def add_keys(self, keys):
     context = self.field.get_context(self.record)
     domain = self.field.domain_get(self.record)
     batchlen = min(10, CONFIG['client.limit'])
     for i in xrange(0, len(keys), batchlen):
         sub_keys = keys[i:i + batchlen]
         try:
             key_ids = RPCExecute('model', self.schema_model, 'search',
                 [('name', 'in', sub_keys), domain], 0,
                 CONFIG['client.limit'], None, context=context)
         except RPCException:
             key_ids = []
         if not key_ids:
             continue
         try:
             values = RPCExecute('model', self.schema_model,
                 'get_keys', key_ids, context=context)
         except RPCException:
             values = []
         if not values:
             continue
         self.keys.update({k['name']: k for k in values})
Example #15
0
 def add_name_suffix(name, context=None):
     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'],
                            context=context)
     name_suffix = _(', ').join([x['rec_name'] for x in rec_names])
     if len(data['ids']) > max_records:
         name_suffix += _(',\u2026')
     return _('%s (%s)') % (name, name_suffix)
Example #16
0
        def update(widget, search_text, callback=None):
            def end():
                if callback:
                    callback()
                return False

            if search_text != widget.get_text():
                return end()
            gmodel = global_search_completion.get_model()
            if not search_text or not gmodel:
                gmodel.clear()
                gmodel.search_text = search_text
                return end()
            if getattr(gmodel, 'search_text', None) == search_text:
                return end()

            def set_result(result):
                try:
                    result = result()
                except RPCException:
                    result = []
                if search_text != widget.get_text():
                    if callback:
                        callback()
                    return False
                gmodel.clear()
                for r in result:
                    _, model, model_name, record_id, record_name, icon = r
                    if icon:
                        text = common.to_xml(record_name)
                        pixbuf = common.IconFactory.get_pixbuf(
                            icon, Gtk.IconSize.BUTTON)
                    else:
                        text = '<b>%s:</b>\n %s' % (common.to_xml(model_name),
                                                    common.to_xml(record_name))
                        pixbuf = None
                    gmodel.append([pixbuf, text, model, record_id, model_name])
                gmodel.search_text = search_text
                # Force display of popup
                widget.emit('changed')
                end()

            RPCExecute('model',
                       'ir.model',
                       'global_search',
                       search_text,
                       CONFIG['client.limit'],
                       self.menu_screen.model_name,
                       context=self.menu_screen.context,
                       callback=set_result)
            return False
Example #17
0
 def on_write_ids(self, ids):
     if not self.on_write:
         return []
     res = []
     for fnct in self.on_write:
         try:
             res += RPCExecute('model',
                               self.model_name,
                               fnct,
                               ids,
                               context=self.context)
         except RPCException:
             return []
     return list({}.fromkeys(res))
Example #18
0
 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 += _(',...')
     return _('%s (%s)') % (name, name_suffix)
Example #19
0
 def sig_copy(self, widget=None):
     if not common.MODELACCESS[self.model]['create']:
         return
     if not self.modified_save():
         return
     res_ids = self.sel_ids_get()
     try:
         new_ids = RPCExecute('model', self.model, 'copy', res_ids, {},
             context=self.context)
     except RPCException:
         return
     self.screen.load(new_ids)
     self.message_info(_('Working now on the duplicated record(s)!'),
         'green')
Example #20
0
    def translate(self, *args):
        if self.record.id < 0 or self.record.modified:
            common.message(
                _('You need to save the record before adding translations!'))
            return

        try:
            lang_ids = RPCExecute('model', 'ir.lang', 'search', [
                ('translatable', '=', True),
            ])
        except RPCException:
            return

        if not lang_ids:
            common.message(_('No other language available!'))
            return
        try:
            languages = RPCExecute('model', 'ir.lang', 'read', lang_ids,
                                   ['code', 'name'])
        except RPCException:
            return

        TranslateDialog(self, languages)
Example #21
0
    def search_active(self, active=True):
        if active and not self.parent:
            if not self.fields_view_tree:
                try:
                    self.fields_view_tree = RPCExecute('model',
                        self.model_name, 'fields_view_get', False, 'tree',
                        context=self.context)
                except RPCException:
                    return

            if not self.domain_parser:
                fields = copy.deepcopy(self.fields_view_tree['fields'])
                for name, props in fields.iteritems():
                    if props['type'] not in ('selection', 'reference'):
                        continue
                    if isinstance(props['selection'], (tuple, list)):
                        continue
                    props['selection'] = self.get_selection(props)

                # Filter only fields in XML view
                xml_dom = xml.dom.minidom.parseString(
                    self.fields_view_tree['arch'])
                root_node, = xml_dom.childNodes
                xml_fields = [node_attributes(node).get('name')
                    for node in root_node.childNodes
                    if node.nodeName == 'field']
                fields = collections.OrderedDict(
                    (name, fields[name]) for name in xml_fields)
                for name, string, type_ in (
                        ('id', _('ID'), 'integer'),
                        ('create_uid', _('Creation User'), 'many2one'),
                        ('create_date', _('Creation Date'), 'datetime'),
                        ('write_uid', _('Modification User'), 'many2one'),
                        ('write_date', _('Modification Date'), 'datetime'),
                        ):
                    if name not in fields:
                        fields[name] = {
                            'string': string.decode('utf-8'),
                            'name': name,
                            'type': type_,
                            }
                        if type_ == 'datetime':
                            fields[name]['format'] = '"%H:%M:%S"'

                self.domain_parser = DomainParser(fields)

            self.screen_container.set_screen(self)
            self.screen_container.show_filter()
        else:
            self.screen_container.hide_filter()
Example #22
0
 def _button_instance(self, button):
     record = self.current_record
     args = record.expr_eval(button.get('change', []))
     values = record._get_on_change_args(args)
     try:
         changes = RPCExecute('model',
                              self.model_name,
                              button['name'],
                              values,
                              context=self.context)
     except RPCException:
         return
     record.set_on_change(changes)
     record.signal('record-changed')
Example #23
0
 def save(self, force_reload=True):
     if self.id < 0 or self.modified:
         if self.id < 0:
             value = self.get()
             try:
                 res, = RPCExecute('model',
                                   self.model_name,
                                   'create', [value],
                                   context=self.get_context())
             except RPCException:
                 return False
             old_id = self.id
             self.id = res
             self.group.id_changed(old_id)
         elif self.modified:
             value = self.get()
             if value:
                 context = self.get_context()
                 context = context.copy()
                 context['_timestamp'] = self.get_timestamp()
                 try:
                     RPCExecute('model',
                                self.model_name,
                                'write', [self.id],
                                value,
                                context=context)
                 except RPCException:
                     return False
         self.cancel()
         if force_reload:
             self.reload()
         if self.group:
             self.group.written(self.id)
     if self.parent:
         self.parent.modified_fields.pop(self.group.child_name, None)
         self.parent.save(force_reload=force_reload)
     return self.id
Example #24
0
    def _sig_add(self, *args, **kwargs):
        if not self.focus_out:
            return
        access = common.MODELACCESS[self.screen.model_name]
        if not access['write'] or not access['read']:
            return
        self.view.set_value()
        domain = self.field.domain_get(self.record)
        context = self.field.context_get(self.record)
        domain = [domain, self.record.expr_eval(self.attrs.get('add_remove'))]
        removed_ids = self.field.get_removed_ids(self.record)

        self.focus_out = False
        try:
            if self.wid_text.get_text():
                dom = [('rec_name', 'ilike',
                        '%' + self.wid_text.get_text() + '%'),
                    ['OR', domain, ('id', 'in', removed_ids)]]
            else:
                dom = ['OR', domain, ('id', 'in', removed_ids)]
            ids = RPCExecute('model', self.attrs['relation'], 'search', dom,
                    0, CONFIG['client.limit'], None, context=context)
        except RPCException:
            self.focus_out = True
            return False

        sequence = None
        if self.screen.current_view.view_type == 'tree':
            sequence = self.screen.current_view.widget_tree.sequence

        def callback(result):
            self.focus_out = True
            if result:
                ids = [x[0] for x in result]
                self.screen.load(ids, modified=True)
                self.screen.display(res_id=ids[0])
                if sequence:
                    self.screen.group.set_sequence(field=sequence)
            self.screen.set_cursor()
            self.wid_text.set_text('')

        if len(ids) != 1 or kwargs.get('win_search', False):
            WinSearch(self.attrs['relation'], callback, sel_multi=True,
                ids=ids, context=context, domain=domain,
                view_ids=self.attrs.get('view_ids', '').split(','),
                views_preload=self.attrs.get('views', {}),
                new=self.but_new.get_property('sensitive'))
        else:
            callback([(i, None) for i in ids])
Example #25
0
 def get_inactive_selection(self, value):
     if 'relation' not in self.attrs:
         return ''
     for val, text in self.inactive_selection:
         if str(val) == str(value):
             return text
     else:
         try:
             result, = RPCExecute('model', self.attrs['relation'], 'read',
                                  [value], ['rec_name'])
             self.inactive_selection.append(
                 (result['id'], result['rec_name']))
             return result['rec_name']
         except RPCException:
             return ''
Example #26
0
    def on_change(self, fieldnames):
        values = {}
        for fieldname in fieldnames:
            on_change = self.group.fields[fieldname].attrs.get('on_change')
            if not on_change:
                continue
            values.update(self._get_on_change_args(on_change))

        if values:
            try:
                if len(fieldnames) == 1:
                    fieldname, = fieldnames
                    changes = []
                    changes.append(RPCExecute(
                            'model', self.model_name, 'on_change_' + fieldname,
                            values, context=self.get_context()))
                else:
                    changes = RPCExecute(
                        'model', self.model_name, 'on_change',
                        values, fieldnames, context=self.get_context())
            except RPCException:
                return
            for change in changes:
                self.set_on_change(change)
Example #27
0
 def callback(result):
     if result:
         self.send_modified()
         try:
             new_fields = RPCExecute('model',
                                     self.schema_model,
                                     'get_keys', [r[0] for r in result],
                                     context=context)
         except RPCException:
             new_fields = []
         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'])
     self.wid_text.set_text('')
Example #28
0
 def execute(action, data, context=None, keyword=False):
     if isinstance(action, int):
         # Must be executed synchronously to avoid double execution
         # on double click.
         action = RPCExecute(
             'model', 'ir.action', 'get_action_value', action,
             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)
Example #29
0
 def fill_predefwin(self):
     try:
         exports = RPCExecute(
             'model', 'ir.export', 'search_read',
             [('resource', '=', self.model)], 0, None, None,
             ['name', 'export_fields.name'],
             context=self.context)
     except RPCException:
         return
     for export in exports:
         self.predef_model.append((
                 export['id'],
                 [f['name'] for f in export['export_fields.']],
                 export['name']))
     self.pref_export.set_model(self.predef_model)
Example #30
0
    def update(search_text, domain):
        if not entry.props.window:
            return False
        if search_text != entry.get_text():
            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', likify(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():
                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:
            logger.warning("Unable to search for completion of %s",
                           model,
                           exc_info=True)
        return False