changeset 12e08efd3872 in tryton:default
details: https://hg.tryton.org/tryton?cmd=changeset;node=12e08efd3872
description:
Manage deletable and writable state from ir.rule
issue9357
review290101002
diffstat:
CHANGELOG | 1 +
tryton/gui/window/form.py | 14 ++++++++++-
tryton/gui/window/view_form/model/record.py | 16 ++++++++++++-
tryton/gui/window/view_form/screen/screen.py | 21 ++++++++++++++++--
tryton/gui/window/view_form/view/form_gtk/one2many.py | 8 +++++-
tryton/gui/window/win_form.py | 5 +++-
6 files changed, 55 insertions(+), 10 deletions(-)
diffs (217 lines):
diff -r 388550da810a -r 12e08efd3872 CHANGELOG
--- a/CHANGELOG Tue Sep 22 10:18:39 2020 +0200
+++ b/CHANGELOG Wed Sep 23 10:04:19 2020 +0200
@@ -1,3 +1,4 @@
+* Manage deletable and writable state
* Support e-mail template
* Send e-mail via the server
* Support PYSON comparison of date and datetime
diff -r 388550da810a -r 12e08efd3872 tryton/gui/window/form.py
--- a/tryton/gui/window/form.py Tue Sep 22 10:18:39 2020 +0200
+++ b/tryton/gui/window/form.py Wed Sep 23 10:04:19 2020 +0200
@@ -302,7 +302,8 @@
self.menu_buttons[name].props.sensitive = False
def sig_remove(self, widget=None):
- if not common.MODELACCESS[self.model]['delete']:
+ if (not common.MODELACCESS[self.model]['delete']
+ or not self.screen.deletable):
return
if self.screen.current_view.view_type == 'form':
msg = _('Are you sure to remove this record?')
@@ -379,7 +380,8 @@
# Called from button so we must save the tree state
self.screen.save_tree_state()
if not (common.MODELACCESS[self.model]['write']
- or common.MODELACCESS[self.model]['create']):
+ or common.MODELACCESS[self.model]['create']
+ or self.screen.writable):
return
if self.screen.save_current():
self.message_info(_('Record saved.'), Gtk.MessageType.INFO)
@@ -423,6 +425,7 @@
break
self.screen.display(set_cursor=set_cursor)
self.message_info()
+ self.set_buttons_sensitive()
self.activate_save()
self.screen.count_tab_domain()
return True
@@ -509,11 +512,18 @@
can_be_sensitive |= any(
b.attrs.get('keyword', 'action') == action_type
for b in screen.get_buttons())
+ elif button_id == 'save':
+ can_be_sensitive &= not self.screen.readonly
button.props.sensitive = (bool(signal_data[0])
and can_be_sensitive)
button_switch = self.buttons['switch']
button_switch.props.sensitive = self.screen.number_of_views > 1
+ menu_delete = self.menu_buttons['remove']
+ menu_delete.props.sensitive = self.screen.deletable
+ menu_save = self.menu_buttons['save']
+ menu_save.props.sensitive = not self.screen.readonly
+
msg = name + ' / ' + str(signal_data[1])
if signal_data[1] < signal_data[2]:
msg += _(' of ') + str(signal_data[2])
diff -r 388550da810a -r 12e08efd3872 tryton/gui/window/view_form/model/record.py
--- a/tryton/gui/window/view_form/model/record.py Tue Sep 22 10:18:39
2020 +0200
+++ b/tryton/gui/window/view_form/model/record.py Wed Sep 23 10:04:19
2020 +0200
@@ -28,6 +28,8 @@
self.state_attrs = {}
self.modified_fields = {}
self._timestamp = None
+ self._write = True
+ self._delete = True
self.resources = None
self.button_clicks = {}
self.links_counts = {}
@@ -73,7 +75,7 @@
in ('many2one', 'one2one', 'reference')))
if 'rec_name' not in fnames:
fnames.append('rec_name')
- fnames.append('_timestamp')
+ fnames.extend(['_timestamp', '_write', '_delete'])
record_context = self.get_context()
if loading == 'eager':
@@ -226,10 +228,17 @@
deleted = property(get_deleted)
def get_readonly(self):
- return self.deleted or self.removed or self.exception
+ return (self.deleted
+ or self.removed
+ or self.exception
+ or not self._write)
readonly = property(get_readonly)
+ @property
+ def deletable(self):
+ return self._delete
+
def fields_get(self):
return self.group.fields
@@ -436,6 +445,9 @@
if not self._timestamp:
self._timestamp = value
continue
+ if fieldname in {'_write', '_delete'}:
+ setattr(self, fieldname, value)
+ continue
if fieldname not in self.group.fields:
if fieldname == 'rec_name':
self.value['rec_name'] = value
diff -r 388550da810a -r 12e08efd3872
tryton/gui/window/view_form/screen/screen.py
--- a/tryton/gui/window/view_form/screen/screen.py Tue Sep 22 10:18:39
2020 +0200
+++ b/tryton/gui/window/view_form/screen/screen.py Wed Sep 23 10:04:19
2020 +0200
@@ -142,6 +142,19 @@
def __repr__(self):
return '<Screen %s at %s>' % (self.model_name, id(self))
+ @property
+ def readonly(self):
+ return (self.__readonly
+ or any(r.readonly for r in self.selected_records))
+
+ @readonly.setter
+ def readonly(self, value):
+ self.__readonly = value
+
+ @property
+ def deletable(self):
+ return all(r.deletable for r in self.selected_records)
+
def search_active(self, active=True):
if active and not self.parent:
self.screen_container.set_screen(self)
@@ -413,7 +426,7 @@
def new_group(self, context=None):
context = context if context is not None else self.context
self.group = Group(self.model_name, {}, domain=self.domain,
- context=context, readonly=self.readonly)
+ context=context, readonly=self.__readonly)
def _group_cleared(self, group, signal):
for view in self.views:
@@ -1104,7 +1117,7 @@
@property
def selected_records(self):
- return self.current_view.selected_records
+ return self.current_view.selected_records if self.current_view else []
def clear(self):
self.current_record = None
@@ -1196,7 +1209,9 @@
if access['create']:
self.new()
elif action == 'delete':
- if access['delete']:
+ if (access['delete']
+ and (self.current_record.deletable
+ if self.current_record else True)):
self.remove(delete=not self.parent,
force_remove=not self.parent)
elif action == 'remove':
diff -r 388550da810a -r 12e08efd3872
tryton/gui/window/view_form/view/form_gtk/one2many.py
--- a/tryton/gui/window/view_form/view/form_gtk/one2many.py Tue Sep 22
10:18:39 2020 +0200
+++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py Wed Sep 23
10:04:19 2020 +0200
@@ -268,6 +268,7 @@
if isinstance(self._position, int):
first = self._position <= 1
last = self._position >= self._length
+ deletable = self.screen.deletable
self.but_new.set_sensitive(bool(
not self._readonly
@@ -277,6 +278,7 @@
self.but_del.set_sensitive(bool(
not self._readonly
and self.attrs.get('delete', True)
+ and deletable
and self._position
and access['delete']))
self.but_undel.set_sensitive(bool(
@@ -427,11 +429,13 @@
def _sig_remove(self, widget, remove=False):
access = common.MODELACCESS[self.screen.model_name]
+ writable = not self.screen.readonly
+ deletable = self.screen.deletable
if remove:
- if not access['write'] or not access['read']:
+ if not access['write'] or not writable or not access['read']:
return
else:
- if not access['delete']:
+ if not access['delete'] or not deletable:
return
self.screen.remove(remove=remove)
diff -r 388550da810a -r 12e08efd3872 tryton/gui/window/win_form.py
--- a/tryton/gui/window/win_form.py Tue Sep 22 10:18:39 2020 +0200
+++ b/tryton/gui/window/win_form.py Wed Sep 23 10:04:19 2020 +0200
@@ -322,6 +322,9 @@
def _sig_label(self, screen, signal_data):
name = '_'
access = common.MODELACCESS[screen.model_name]
+ deletable = True
+ if screen.current_record:
+ deletable = screen.current_record.deletable
readonly = screen.group.readonly
if signal_data[0] >= 1:
name = str(signal_data[0])
@@ -335,7 +338,7 @@
self.but_pre.set_sensitive(True)
else:
self.but_pre.set_sensitive(False)
- if access['delete'] and not readonly:
+ if access['delete'] and not readonly and deletable:
self.but_del.set_sensitive(True)
self.but_undel.set_sensitive(True)
else: