diff --git a/CHANGELOG b/CHANGELOG index 2abd1968d9..27e8986772 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Manage create/delete field access * Add dynamic size limit on the One2Many, Many2Many and Char * Search only on fields in XML view * Cache action keyword diff --git a/tryton/gui/window/view_form/view/form_gtk/many2many.py b/tryton/gui/window/view_form/view/form_gtk/many2many.py index 0dec4a31b1..b5db442405 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2many.py @@ -150,7 +150,8 @@ class Many2Many(WidgetInterface): 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', {})) + views_preload=self.attrs.get('views', {}), + new=self.attrs.get('create', True)) else: callback([(i, None) for i in ids]) diff --git a/tryton/gui/window/view_form/view/form_gtk/many2one.py b/tryton/gui/window/view_form/view/form_gtk/many2one.py index 0de9105435..60c75a0bb1 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2one.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2one.py @@ -76,7 +76,8 @@ class Many2One(WidgetInterface): def _readonly_set(self, value): self._readonly = value self.wid_text.set_editable(not value) - self.but_new.set_sensitive(not value) + self.but_new.set_sensitive(not value + and self.attrs.get('create', True)) if value: self.widget.set_focus_chain([]) else: @@ -160,7 +161,8 @@ class Many2One(WidgetInterface): WinSearch(model, callback, sel_multi=False, ids=ids, context=context, domain=domain, view_ids=self.attrs.get('view_ids', '').split(','), - views_preload=self.attrs.get('views', {})) + views_preload=self.attrs.get('views', {}), + new=self.but_new.get_property('sensitive')) return self.focus_out = True self.display(self.record, self.field) @@ -249,7 +251,8 @@ class Many2One(WidgetInterface): WinSearch(model, callback, sel_multi=False, ids=ids, context=context, domain=domain, view_ids=self.attrs.get('view_ids', '').split(','), - views_preload=self.attrs.get('views', {})) + views_preload=self.attrs.get('views', {}), + new=self.but_new.get_property('sensitive')) return self.focus_out = True self.display(self.record, self.field) @@ -258,10 +261,13 @@ class Many2One(WidgetInterface): def sig_key_press(self, widget, event, *args): editable = self.wid_text.get_editable() - if event.keyval == gtk.keysyms.F3 and editable: + if (event.keyval == gtk.keysyms.F3 + and editable + and self.but_new.get_property('sensitive')): self.sig_new(widget, event) return True - elif event.keyval == gtk.keysyms.F2: + elif (event.keyval == gtk.keysyms.F2 + and self.but_open.get_property('sensitive')): self.sig_edit(widget) return True elif (event.keyval in (gtk.keysyms.Tab, gtk.keysyms.Return) @@ -297,7 +303,7 @@ class Many2One(WidgetInterface): model = self.get_model() if model: access = common.MODELACCESS[model] - if not access['create']: + if not access['create'] or not self.attrs.get('create', True): self.but_new.set_sensitive(False) if not access['read']: self.but_open.set_sensitive(False) diff --git a/tryton/gui/window/view_form/view/form_gtk/one2many.py b/tryton/gui/window/view_form/view/form_gtk/one2many.py index f1a8804eed..cd79352b4a 100644 --- a/tryton/gui/window/view_form/view/form_gtk/one2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py @@ -187,8 +187,9 @@ class One2Many(WidgetInterface): and widget == self.screen.widget: self._sig_edit(widget) return False - if event.keyval in (gtk.keysyms.Delete, gtk.keysyms.KP_Delete) \ - and widget == self.screen.widget: + if (event.keyval in (gtk.keysyms.Delete, gtk.keysyms.KP_Delete) + and widget == self.screen.widget + and self.but_del.get_property('sensitive')): self._sig_remove(widget) return False if event.keyval == gtk.keysyms.Insert and widget == self.screen.widget: @@ -220,8 +221,10 @@ class One2Many(WidgetInterface): def _readonly_set(self, value): self._readonly = value - self.but_new.set_sensitive(not value) - self.but_del.set_sensitive(not value) + self.but_new.set_sensitive(not value + and self.attrs.get('create', True)) + self.but_del.set_sensitive(not value + and self.attrs.get('delete', True)) self.but_undel.set_sensitive(not value) if self.attrs.get('add_remove'): self.wid_text.set_sensitive(not value) @@ -351,7 +354,8 @@ class One2Many(WidgetInterface): 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', {})) + views_preload=self.attrs.get('views', {}), + new=self.but_new.get_property('sensitive')) else: callback([(i, None) for i in ids]) @@ -369,7 +373,8 @@ class One2Many(WidgetInterface): if signal_data[0] >= 1: name = str(signal_data[0]) self.but_open.set_sensitive(True) - self.but_del.set_sensitive(not self._readonly) + self.but_del.set_sensitive(not self._readonly + and self.attrs.get('delete', True)) if self.attrs.get('add_remove'): self.but_remove.set_sensitive(not self._readonly) self.but_add.set_sensitive(not self._readonly @@ -401,7 +406,7 @@ class One2Many(WidgetInterface): super(One2Many, self).display(record, field) access = common.MODELACCESS[self.screen.model_name] - if not access['create']: + if not access['create'] or not self.attrs.get('create', True): self.but_new.set_sensitive(False) if not access['write'] or not access['read']: if hasattr(self, 'but_add'): @@ -410,7 +415,7 @@ class One2Many(WidgetInterface): self.but_remove.set_sensitive(False) if not access['read']: self.but_open.set_sensitive(False) - if not access['delete']: + if not access['delete'] or not self.attrs.get('delete', True): self.but_del.set_sensitive(False) if field is None: diff --git a/tryton/gui/window/view_form/view/form_gtk/parser.py b/tryton/gui/window/view_form/view/form_gtk/parser.py index 61ebbf47c6..01fdd9df84 100644 --- a/tryton/gui/window/view_form/view/form_gtk/parser.py +++ b/tryton/gui/window/view_form/view/form_gtk/parser.py @@ -439,7 +439,7 @@ class ParserForm(ParserInterface): for attr_name in ('relation', 'domain', 'selection', 'relation_field', 'string', 'views', 'invisible', 'add_remove', 'sort', 'context', 'size', 'filename', - 'autocomplete', 'translate'): + 'autocomplete', 'translate', 'create', 'delete'): if attr_name in fields[name].attrs and \ not attr_name in attrs: attrs[attr_name] = fields[name].attrs[attr_name] diff --git a/tryton/gui/window/win_search.py b/tryton/gui/window/win_search.py index 2de567f5ba..8e4a6c4981 100644 --- a/tryton/gui/window/win_search.py +++ b/tryton/gui/window/win_search.py @@ -14,7 +14,7 @@ _ = gettext.gettext class WinSearch(NoModal): def __init__(self, model, callback, sel_multi=True, ids=None, context=None, - domain=None, view_ids=None, views_preload=None): + domain=None, view_ids=None, views_preload=None, new=True): NoModal.__init__(self) if views_preload is None: views_preload = {} @@ -39,7 +39,9 @@ class WinSearch(NoModal): self.but_ok = self.win.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) self.but_ok.add_accelerator('clicked', self.accel_group, gtk.keysyms.Return, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) - self.but_new = self.win.add_button(gtk.STOCK_NEW, gtk.RESPONSE_ACCEPT) + if new and common.MODELACCESS[model]['create']: + self.but_new = self.win.add_button(gtk.STOCK_NEW, + gtk.RESPONSE_ACCEPT) hbox = gtk.HBox() hbox.show()