From 156d78de8667ce451edbf729916ccbb0ada9c00c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Wed, 20 Jun 2012 18:13:12 +0200 Subject: [PATCH] Add dynamic size limit on the One2Many, Many2Many and Char review394003 --- CHANGELOG | 1 + .../window/view_form/view/form_gtk/char.py | 16 ++++++++++++-- .../view_form/view/form_gtk/many2many.py | 9 ++++++++ .../view_form/view/form_gtk/one2many.py | 22 ++++++++++++++++--- tryton/gui/window/win_form.py | 9 ++++++-- 5 files changed, 50 insertions(+), 7 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6283f09f4d..2abd1968d9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add dynamic size limit on the One2Many, Many2Many and Char * Search only on fields in XML view * Cache action keyword * Always use cached views diff --git a/tryton/gui/window/view_form/view/form_gtk/char.py b/tryton/gui/window/view_form/view/form_gtk/char.py index 6a13741280..d29df108db 100644 --- a/tryton/gui/window/view_form/view/form_gtk/char.py +++ b/tryton/gui/window/view_form/view/form_gtk/char.py @@ -34,8 +34,6 @@ class Char(WidgetInterface, TranslateMixin): focus_entry = self.entry focus_entry.set_property('activates_default', True) - focus_entry.set_width_chars(int(attrs.get('size', -1))) - focus_entry.set_max_length(int(attrs.get('size', 0))) focus_entry.connect('activate', self.sig_activate) focus_entry.connect('focus-in-event', lambda x, y: self._focus_in()) focus_entry.connect('focus-out-event', lambda x, y: self._focus_out()) @@ -102,6 +100,20 @@ class Char(WidgetInterface, TranslateMixin): self.entry_store.append((row,)) elif self.autocomplete: self.entry_store.clear() + + # Set size + if self.autocomplete: + size_entry = self.entry.get_child() + else: + size_entry = self.entry + if record: + field_size = record.expr_eval(self.attrs.get('size')) + size_entry.set_width_chars(field_size or -1) + size_entry.set_max_length(field_size or 0) + else: + size_entry.set_width_chars(-1) + size_entry.set_max_length(0) + if not field: value = '' else: 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 8cfdbc6723..0dec4a31b1 100644 --- a/tryton/gui/window/view_form/view/form_gtk/many2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/many2many.py @@ -181,6 +181,15 @@ class Many2Many(WidgetInterface): self.but_add.set_sensitive(not value) def _sig_label(self, screen, signal_data): + if self.record and self.field: + field_size = self.record.expr_eval(self.attrs.get('size')) + m2m_size = len(self.field.get_eval(self.record)) + size_limit = (field_size is not None + and m2m_size >= field_size >= 0) + else: + size_limit = False + + self.but_add.set_sensitive(not size_limit) if signal_data[0] >= 1: self.but_remove.set_sensitive(not self._readonly) else: 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 34acf7b962..33a2248652 100644 --- a/tryton/gui/window/view_form/view/form_gtk/one2many.py +++ b/tryton/gui/window/view_form/view/form_gtk/one2many.py @@ -253,8 +253,10 @@ class One2Many(WidgetInterface): self.screen.current_view.widget.set_sensitive(True) update_sequence() else: + field_size = self.record.expr_eval(self.attrs.get('size')) or -1 + field_size -= len(self.field.get_eval(self.record)) + 1 WinForm(self.screen, lambda a: update_sequence(), new=True, - many=True, context=ctx) + many=field_size, context=ctx) def _sig_edit(self, widget=None): if not common.MODELACCESS[self.screen.model_name]['read']: @@ -349,12 +351,23 @@ class One2Many(WidgetInterface): def _sig_label(self, screen, signal_data): name = '_' + if self.record and self.field: + field_size = self.record.expr_eval(self.attrs.get('size')) + o2m_size = len(self.field.get_eval(self.record)) + size_limit = (field_size is not None + and o2m_size >= field_size >= 0) + else: + size_limit = False + + self.but_new.set_sensitive(not size_limit) if signal_data[0] >= 1: name = str(signal_data[0]) self.but_open.set_sensitive(True) self.but_del.set_sensitive(not self._readonly) if self.attrs.get('add_remove'): self.but_remove.set_sensitive(not self._readonly) + self.but_add.set_sensitive(not self._readonly + and not size_limit) if signal_data[0] < signal_data[1]: self.but_next.set_sensitive(True) else: @@ -364,15 +377,17 @@ class One2Many(WidgetInterface): else: self.but_pre.set_sensitive(False) self.but_del.set_sensitive(not self._readonly) - self.but_undel.set_sensitive(not self._readonly) + self.but_undel.set_sensitive(not self._readonly and not size_limit) else: self.but_open.set_sensitive(False) self.but_del.set_sensitive(False) - self.but_undel.set_sensitive(False) + self.but_undel.set_sensitive(not size_limit) self.but_next.set_sensitive(False) self.but_pre.set_sensitive(False) if self.attrs.get('add_remove'): self.but_remove.set_sensitive(False) + self.but_add.set_sensitive(not size_limit) + line = '(%s/%s)' % (name, signal_data[1]) self.label.set_text(line) @@ -399,6 +414,7 @@ class One2Many(WidgetInterface): self.screen.display() return False new_group = field.get_client(record) + if id(self.screen.group) != id(new_group): self.screen.group = new_group if (self.screen.current_view.view_type == 'tree') \ diff --git a/tryton/gui/window/win_form.py b/tryton/gui/window/win_form.py index f659b232ff..6f12ea91d9 100644 --- a/tryton/gui/window/win_form.py +++ b/tryton/gui/window/win_form.py @@ -16,11 +16,12 @@ class WinForm(NoModal): "Form window" def __init__(self, screen, callback, view_type='form', - new=False, many=False, domain=None, context=None, + new=False, many=0, domain=None, context=None, save_current=False): NoModal.__init__(self) self.screen = screen self.callback = callback + self.many = many self.domain = domain self.context = context self.save_current = save_current @@ -56,7 +57,7 @@ class WinForm(NoModal): self.but_ok = self.win.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK) - if new and many: + if new and self.many: self.but_ok.add_accelerator('clicked', self.accel_group, gtk.keysyms.Return, gtk.gdk.CONTROL_MASK | gtk.gdk.SHIFT_MASK, @@ -401,6 +402,10 @@ class WinForm(NoModal): self.screen.new(context=self.context) self.screen.current_view.display() self.screen.set_cursor(new=True) + self.many -= 1 + if self.many == 0: + self.but_new.set_sensitive(False) + self.win.set_default_response(gtk.RESPONSE_OK) def destroy(self): self.screen.screen_container.alternate_view = False