details: https://code.tryton.org/tryton/commit/234f0a089153
branch: default
user: Cédric Krier <[email protected]>
date: Tue May 12 15:40:54 2026 +0200
description:
Add filters attribute for binary and image widgets
Closes #14822
diffstat:
sao/CHANGELOG | 1 +
sao/src/view/form.js | 10 ++++--
tryton/CHANGELOG | 1 +
tryton/tryton/gui/window/view_form/view/form_gtk/binary.py | 18 +++++++++--
tryton/tryton/gui/window/view_form/view/form_gtk/image.py | 12 +-------
tryton/tryton/gui/window/view_form/view/list_gtk/widget.py | 20 +++++++++++++-
trytond/CHANGELOG | 1 +
trytond/doc/topics/views/index.rst | 8 +++++
trytond/trytond/ir/ui/form.rnc | 1 +
trytond/trytond/ir/ui/tree.rnc | 1 +
10 files changed, 54 insertions(+), 19 deletions(-)
diffs (194 lines):
diff -r 99660f995c4a -r 234f0a089153 sao/CHANGELOG
--- a/sao/CHANGELOG Fri Apr 10 11:29:50 2026 +0200
+++ b/sao/CHANGELOG Tue May 12 15:40:54 2026 +0200
@@ -1,3 +1,4 @@
+* Support filters attribute for binary and image widgets
* Use search window to delete/remove records from xxx2Many widgets
Version 8.0.0 - 2026-04-20
diff -r 99660f995c4a -r 234f0a089153 sao/src/view/form.js
--- a/sao/src/view/form.js Fri Apr 10 11:29:50 2026 +0200
+++ b/sao/src/view/form.js Tue May 12 15:40:54 2026 +0200
@@ -4521,6 +4521,10 @@
this, view, attributes);
this.filename = attributes.filename || null;
},
+ default_filters: '',
+ get filters() {
+ return this.attributes.filters || this.default_filters;
+ },
toolbar: function(class_) {
var group = jQuery('<div/>', {
'class': class_,
@@ -4539,6 +4543,7 @@
this.input_select = jQuery('<input/>', {
'type': 'file',
}).change(this.select.bind(this));
+ this.input_select.attr('accept', this.filters);
this.but_select = jQuery('<div/>', {
'class': 'btn btn-default input-file',
'type': 'button',
@@ -4856,9 +4861,6 @@
break;
}
var group = this.toolbar('btn-group');
- this.input_select.attr(
- 'accept',
- 'image/png,image/jpeg,image/gif,.png,.jpg,.gif,.tif,.xpm');
if (!attributes.readonly) {
jQuery('<div/>', {
'class': 'text-center caption',
@@ -4866,6 +4868,8 @@
}
this._readonly = false;
},
+ default_filters: (
+ 'image/png,image/jpeg,image/gif,.png,.jpg,.gif,.tif,.xpm'),
set_readonly: function(readonly) {
Sao.View.Form.Image._super.set_readonly.call(this, readonly);
var record = this.record;
diff -r 99660f995c4a -r 234f0a089153 tryton/CHANGELOG
--- a/tryton/CHANGELOG Fri Apr 10 11:29:50 2026 +0200
+++ b/tryton/CHANGELOG Tue May 12 15:40:54 2026 +0200
@@ -1,3 +1,4 @@
+* Support filters attribute for binary and image widgets
* Use search window to delete/remove records from xxx2Many widgets
Version 8.0.0 - 2026-04-20
diff -r 99660f995c4a -r 234f0a089153
tryton/tryton/gui/window/view_form/view/form_gtk/binary.py
--- a/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py Fri Apr
10 11:29:50 2026 +0200
+++ b/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py Tue May
12 15:40:54 2026 +0200
@@ -64,12 +64,22 @@
def filename_field(self):
return self.record.group.fields.get(self.filename)
+ default_filters = None
+
@property
def filters(self):
- filter_all = Gtk.FileFilter()
- filter_all.set_name(_('All files'))
- filter_all.add_pattern("*")
- return [filter_all]
+ file_filter = Gtk.FileFilter()
+ if filters := self.attrs.get('filters', self.default_filters):
+ file_filter.set_name(_("All Supported Types"))
+ for type in filters.split(','):
+ if type.startswith('.'):
+ file_filter.add_pattern(type)
+ else:
+ file_filter.add_mime_type(type)
+ else:
+ file_filter.set_name(_("All files"))
+ file_filter.add_pattern("*")
+ return [file_filter]
@property
def preview(self):
diff -r 99660f995c4a -r 234f0a089153
tryton/tryton/gui/window/view_form/view/form_gtk/image.py
--- a/tryton/tryton/gui/window/view_form/view/form_gtk/image.py Fri Apr 10
11:29:50 2026 +0200
+++ b/tryton/tryton/gui/window/view_form/view/form_gtk/image.py Tue May 12
15:40:54 2026 +0200
@@ -47,17 +47,7 @@
self._readonly = False
- @property
- def filters(self):
- filters = super().filters
- filter_image = Gtk.FileFilter()
- filter_image.set_name(_('Images'))
- for mime in ("image/png", "image/jpeg", "image/gif"):
- filter_image.add_mime_type(mime)
- for pat in ("*.png", "*.jpg", "*.gif", "*.tif", "*.xpm"):
- filter_image.add_pattern(pat)
- filters.insert(0, filter_image)
- return filters
+ default_filters = 'image/png,image/jpeg,image/gif,.png,.jpg,.gif,.tif,.xpm'
def _readonly_set(self, value):
self._readonly = value
diff -r 99660f995c4a -r 234f0a089153
tryton/tryton/gui/window/view_form/view/list_gtk/widget.py
--- a/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py Fri Apr
10 11:29:50 2026 +0200
+++ b/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py Tue May
12 15:40:54 2026 +0200
@@ -699,6 +699,24 @@
class _BinarySelect(_BinaryIcon):
+
+ default_filters = None
+
+ @property
+ def filters(self):
+ file_filter = Gtk.FileFilter()
+ if filters := self.attrs.get('filters', self.default_filters):
+ file_filter.set_name(_("All Supported Types"))
+ for type in filters.split(','):
+ if type.startswith('.'):
+ file_filter.add_pattern(type)
+ else:
+ file_filter.add_mime_type(type)
+ else:
+ file_filter.set_name(_("All files"))
+ file_filter.add_pattern("*")
+ return [file_filter]
+
def clicked(self, renderer, path):
record, field = self._get_record_field_from_path(path)
if hasattr(field, 'get_size'):
@@ -715,7 +733,7 @@
field.set_client(record, None)
else:
def _select():
- filename = file_selection(_('Open...'))
+ filename = file_selection(_("Select"), filters=self.filters)
if filename:
with open(filename, 'rb') as fp:
field.set_client(record, fp.read())
diff -r 99660f995c4a -r 234f0a089153 trytond/CHANGELOG
--- a/trytond/CHANGELOG Fri Apr 10 11:29:50 2026 +0200
+++ b/trytond/CHANGELOG Tue May 12 15:40:54 2026 +0200
@@ -1,3 +1,4 @@
+* Add filters attribute for binary and image widgets
* Move last_user and last_modification to ResourceAccessMixin
* Add check deliverability option to validate email tool
* Add support for AGE to SQLite backend
diff -r 99660f995c4a -r 234f0a089153 trytond/doc/topics/views/index.rst
--- a/trytond/doc/topics/views/index.rst Fri Apr 10 11:29:50 2026 +0200
+++ b/trytond/doc/topics/views/index.rst Tue May 12 15:40:54 2026 +0200
@@ -365,6 +365,14 @@
``rounded`` or ``circle``.
The default value is ``square``.
+``filters``
+ A comma separated list of mime type and file extension (starting with a
+ period ``.``) to restrict the files being shown for selection of binary and
+ image widgets.
+ The default value for binary widget is no filter.
+ The default value for image widget is:
+ ``image/png,image/jpeg,image/gif,.png,.jpg,.gif,.tif,.xpm``.
+
``visible``
When set to ``1`` for :class:`~trytond.model.fields.One2Many` and
:class:`~trytond.model.fields.Many2Many` the client may try to read the
diff -r 99660f995c4a -r 234f0a089153 trytond/trytond/ir/ui/form.rnc
--- a/trytond/trytond/ir/ui/form.rnc Fri Apr 10 11:29:50 2026 +0200
+++ b/trytond/trytond/ir/ui/form.rnc Tue May 12 15:40:54 2026 +0200
@@ -122,6 +122,7 @@
attlist.field &= attribute symbol { text }?
attlist.field &= [a:defaultValue = "1"] attribute grouping { "0" | "1" }?
attlist.field &= [a:defaultValue = "square"] attribute border { "square" |
"circle" | "rounded" }?
+attlist.field &= attribute filters { text }?
attlist.field &= [a:defaultValue = "0"] attribute visible { "0" | "1" }?
image = element image { attlist.image, empty }
attlist.image &= attribute name { text }
diff -r 99660f995c4a -r 234f0a089153 trytond/trytond/ir/ui/tree.rnc
--- a/trytond/trytond/ir/ui/tree.rnc Fri Apr 10 11:29:50 2026 +0200
+++ b/trytond/trytond/ir/ui/tree.rnc Tue May 12 15:40:54 2026 +0200
@@ -75,6 +75,7 @@
attlist.field &= attribute view_ids { text }?
attlist.field &= attribute symbol { text }?
attlist.field &= [a:defaultValue = "1"] attribute grouping { "0" | "1" }?
+attlist.field &= attribute filters { text }?
prefix = element prefix { attlist.affix, empty }
suffix = element suffix { attlist.affix, empty }
attlist.affix &= attribute string { text }?