diff --git a/sao/CHANGELOG b/sao/CHANGELOG index fa2b6a0a78..4540e0db59 100644 --- a/sao/CHANGELOG +++ b/sao/CHANGELOG @@ -1,3 +1,4 @@ +* Support filename extension for Binary field * Use record name as fallback for filename of Binary field * Support filters attribute for binary and image widgets * Use search window to delete/remove records from xxx2Many widgets diff --git a/sao/src/view/form.js b/sao/src/view/form.js index 251710bb01..0c617012c3 100644 --- a/sao/src/view/form.js +++ b/sao/src/view/form.js @@ -4595,6 +4595,12 @@ function eval_pyson(value){ Sao.common.get_input_data(this.input_select, function(data, filename) { field.set_client(record, data); if (filename_field) { + let ext = field.description.filename_ext + if (ext) { + if (filename.endsWith(`.${ext}`)) { + filename = filename.slice(0, -`.${ext}`.length); + } + } filename_field.set_client(record, filename); } }, !field.get_size); @@ -4654,6 +4660,10 @@ function eval_pyson(value){ prm = jQuery.when(name); } return prm.then(name => { + let ext = this.field.description.filename_ext; + if (ext) { + name = `${name}.${ext}`; + } Sao.common.download_file(data, name); }); }); diff --git a/tryton/CHANGELOG b/tryton/CHANGELOG index d7102e542e..e3829c0553 100644 --- a/tryton/CHANGELOG +++ b/tryton/CHANGELOG @@ -1,3 +1,4 @@ +* Support filename extension for Binary field * Use record name as fallback for filename of Binary field * Support filters attribute for binary and image widgets * Use search window to delete/remove records from xxx2Many widgets diff --git a/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py b/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py index 25396ae9e1..5a3918e149 100644 --- a/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py +++ b/tryton/tryton/gui/window/view_form/view/form_gtk/binary.py @@ -114,8 +114,10 @@ class BinaryMixin(Widget): uri = unquote(uri) self.field.set_client(self.record, url_open(uri).read()) if self.filename_field: - self.filename_field.set_client(self.record, - os.path.basename(urlparse(uri).path)) + filename = os.path.basename(urlparse(uri).path) + if ext := self.field.attrs.get('filename_ext'): + filename = filename.removesuffix(os.path.extsep + ext) + self.filename_field.set_client(self.record, filename) def get_data(self): if hasattr(self.field, 'get_data'): @@ -127,11 +129,15 @@ class BinaryMixin(Widget): return data def open_(self, widget=None): - if not self.filename_field: - return - filename = self.filename_field.get(self.record) + filename = None + if self.filename_field: + filename = self.filename_field.get(self.record) + if not filename: + filename = self.record.rec_name() if not filename: return + if ext := self.field.attrs.get('filename_ext'): + filename = ''.join([filename, os.extsep, ext]) file_path = file_write(filename, self.get_data()) root, type_ = os.path.splitext(filename) if type_: @@ -144,6 +150,8 @@ class BinaryMixin(Widget): filename = self.filename_field.get(self.record) if not filename: filename = self.record.rec_name() + if ext := self.field.attrs.get('filename_ext'): + filename = ''.join([filename, os.extsep, ext]) filename = file_selection(_('Save As...'), filename=filename, action=Gtk.FileChooserAction.SAVE) if filename: diff --git a/trytond/CHANGELOG b/trytond/CHANGELOG index 42c361fd41..9ae20ac5bd 100644 --- a/trytond/CHANGELOG +++ b/trytond/CHANGELOG @@ -1,3 +1,4 @@ +* Add filename extension to Binary field * Add filters attribute for binary and image widgets * Move last_user and last_modification to ResourceAccessMixin * Add check deliverability option to validate email tool diff --git a/trytond/doc/ref/fields.rst b/trytond/doc/ref/fields.rst index 05d4f4d99d..de426b3306 100644 --- a/trytond/doc/ref/fields.rst +++ b/trytond/doc/ref/fields.rst @@ -552,8 +552,13 @@ Binary Name of the field that holds the data's filename. Default value is an empty string, which means the data has no filename (in - this case, the filename is hidden, and the "Open" button is hidden when the - widget is set to "image"). + this case, the filename is hidden). + +.. attribute:: Binary.filename_ext + + The extension to append to the :attr:`~Binary.filename`. + + The default value is empty. .. attribute:: Binary.file_id diff --git a/trytond/trytond/model/fields/binary.py b/trytond/trytond/model/fields/binary.py index 2c0ad66c24..fa49e4c569 100644 --- a/trytond/trytond/model/fields/binary.py +++ b/trytond/trytond/model/fields/binary.py @@ -33,8 +33,9 @@ class Binary(Field): def __init__(self, string='', help='', required=False, readonly=False, domain=None, states=None, on_change=None, on_change_with=None, depends=None, context=None, loading='lazy', - filename=None, file_id=None, store_prefix=None): + filename=None, filename_ext=None, file_id=None, store_prefix=None): self.filename = filename + self.filename_ext = filename_ext self.file_id = file_id self.store_prefix = store_prefix super().__init__(string=string, help=help, @@ -165,4 +166,5 @@ class Binary(Field): definition = super().definition(model, language) definition['searchable'] = False definition['filename'] = self.filename + definition['filename_ext'] = self.filename_ext return definition