details: https://code.tryton.org/tryton/commit/027042dcaa8d
branch: default
user: Cédric Krier <[email protected]>
date: Thu Aug 06 14:53:51 2026 +0200
description:
Edit selected One2Many rows at once
Closes #14997
diffstat:
sao/CHANGELOG | 1 +
sao/src/view/form.js | 27 ++++++++---
sao/src/window.js | 4 +
tryton/CHANGELOG | 1 +
tryton/tryton/gui/window/view_form/view/form_gtk/one2many.py | 22 +++++++--
tryton/tryton/gui/window/win_form.py | 6 ++-
6 files changed, 48 insertions(+), 13 deletions(-)
diffs (144 lines):
diff -r 42067e83b4f7 -r 027042dcaa8d sao/CHANGELOG
--- a/sao/CHANGELOG Thu Aug 06 09:46:51 2026 +0200
+++ b/sao/CHANGELOG Thu Aug 06 14:53:51 2026 +0200
@@ -1,3 +1,4 @@
+* Edit the selected One2Many rows sequentially
* Support filename extension for Binary field
* Use record name as fallback for filename of Binary field
* Support filters attribute for binary and image widgets
diff -r 42067e83b4f7 -r 027042dcaa8d sao/src/view/form.js
--- a/sao/src/view/form.js Thu Aug 06 09:46:51 2026 +0200
+++ b/sao/src/view/form.js Thu Aug 06 14:53:51 2026 +0200
@@ -4010,16 +4010,29 @@
return;
}
return this.validate().then(() => {
- var record = this.screen.current_record;
- if (record) {
+ let records = Array.from(this.screen.selected_records);
+ let size = records.length;
+ if (size) {
if (this._popup) {
return;
- } else {
- this._popup = true;
}
- new Sao.Window.Form(this.screen, () => {
- this._popup = false;
- });
+ let edit_next_record = () => {
+ if (records.length) {
+ this.screen.current_record = records.shift();
+ this._popup = true;
+ new Sao.Window.Form(this.screen, (result) => {
+ this._popup = false;
+ if (!result) {
+ records.length = 0;
+ }
+ }, {
+ title: (size > 1 ?
+ `(${size - records.length}/${size})` : ''),
+ on_destroy: edit_next_record,
+ });
+ }
+ };
+ edit_next_record();
}
});
},
diff -r 42067e83b4f7 -r 027042dcaa8d sao/src/window.js
--- a/sao/src/window.js Thu Aug 06 09:46:51 2026 +0200
+++ b/sao/src/window.js Thu Aug 06 14:53:51 2026 +0200
@@ -124,6 +124,7 @@
this.domain = kwargs.domain || null;
this.context = kwargs.context || null;
this.save_current = kwargs.save_current;
+ this.on_destroy = kwargs.on_destroy;
var title_prm = jQuery.when(kwargs.title || '').then(
title => {
if (screen.breadcrumb.length) {
@@ -683,6 +684,9 @@
this.screen.switch_view(this.prev_view.view_type);
}
this.el.modal('hide');
+ if (this.on_destroy) {
+ this.el.on('hidden.bs.modal', () => this.on_destroy());
+ }
}
});
diff -r 42067e83b4f7 -r 027042dcaa8d tryton/CHANGELOG
--- a/tryton/CHANGELOG Thu Aug 06 09:46:51 2026 +0200
+++ b/tryton/CHANGELOG Thu Aug 06 14:53:51 2026 +0200
@@ -1,3 +1,4 @@
+* Edit the selected One2Many rows sequentially
* Support filename extension for Binary field
* Use record name as fallback for filename of Binary field
* Support filters attribute for binary and image widgets
diff -r 42067e83b4f7 -r 027042dcaa8d
tryton/tryton/gui/window/view_form/view/form_gtk/one2many.py
--- a/tryton/tryton/gui/window/view_form/view/form_gtk/one2many.py Thu Aug
06 09:46:51 2026 +0200
+++ b/tryton/tryton/gui/window/view_form/view/form_gtk/one2many.py Thu Aug
06 14:53:51 2026 +0200
@@ -464,16 +464,28 @@
return
if not self._validate():
return
- record = self.screen.current_record
- if record:
+ records = list(self.screen.selected_records)
+ size = len(records)
+ if records:
if self._popup:
return
- else:
- self._popup = True
def callback(result):
self._popup = False
- WinForm(self.screen, callback, prev_view=self.screen.current_view)
+ if not result:
+ records.clear()
+
+ def edit_next_record():
+ if records:
+ self.screen.current_record = records.pop(0)
+ self._popup = True
+ WinForm(
+ self.screen, callback,
+ title=('(%s/%s)' % (size - len(records), size)
+ if size > 1 else ''),
+ prev_view=self.screen.current_view,
+ on_destroy=edit_next_record)
+ edit_next_record()
def _sig_next(self, widget):
if not self._validate():
diff -r 42067e83b4f7 -r 027042dcaa8d tryton/tryton/gui/window/win_form.py
--- a/tryton/tryton/gui/window/win_form.py Thu Aug 06 09:46:51 2026 +0200
+++ b/tryton/tryton/gui/window/win_form.py Thu Aug 06 14:53:51 2026 +0200
@@ -24,7 +24,8 @@
def __init__(self, screen, callback=None, view_type='form',
new=False, many=0, domain=None, context=None,
- save_current=False, title='', defaults=None, prev_view=SENTINEL):
+ save_current=False, title='', defaults=None, prev_view=SENTINEL,
+ on_destroy=None):
tooltips = common.Tooltips()
NoModal.__init__(self)
@@ -37,6 +38,7 @@
self.domain = domain
self.context = context
self.save_current = save_current
+ self.on_destroy = on_destroy
if screen.breadcrumb:
breadcrumb = list(screen.breadcrumb)
if title:
@@ -528,6 +530,8 @@
if getattr(self, 'win', None):
self.win.destroy()
NoModal.destroy(self)
+ if self.on_destroy:
+ self.on_destroy()
def show(self):
self.win.show()