@@ -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
|
||||
|
||||
@@ -4521,6 +4521,10 @@ function eval_pyson(value){
|
||||
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 @@ function eval_pyson(value){
|
||||
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 @@ function eval_pyson(value){
|
||||
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 @@ function eval_pyson(value){
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -64,12 +64,22 @@ class BinaryMixin(Widget):
|
||||
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):
|
||||
|
||||
@@ -47,17 +47,7 @@ class Image(BinaryMixin, Widget):
|
||||
|
||||
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
|
||||
|
||||
@@ -699,6 +699,24 @@ class _BinarySave(_BinaryIcon):
|
||||
|
||||
|
||||
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 @@ class _BinarySelect(_BinaryIcon):
|
||||
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())
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -365,6 +365,14 @@ attributes:
|
||||
``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
|
||||
|
||||
@@ -122,6 +122,7 @@ attlist.field &=
|
||||
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 }
|
||||
|
||||
@@ -75,6 +75,7 @@ attlist.field &= attribute help_field { text }?
|
||||
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 }?
|
||||
|
||||
Reference in New Issue
Block a user