scijava-common
scijava-common copied to clipboard
Add possibility to filter by file type in FileWidget
It would be great if you could ask for a specified file type in a parameter definition:
// @File(label="Open file", style="open", type="*.xls;*.xlsx") inputFile
so that the resulting FileWidget dialog would filter the directory by file type.
Adding more attributes to the @Parameter
annotation in Java land is not really tenable for stuff like this. However, it is a great fit for the existing style
attribute. The point of style
is to provide some "hints" for how you want the input widget to work. So that seems like a good match here.
Maybe we could do something like:
@File(label="Open file", style="open:*.xls;*.xlsx") inputFile
And extend the mechanism as needed (maybe by additional plugins...) to support whatever syntax is useful for specifying file filters. This could include useful stuff like "image formats only" (in all formats ImageJ supports), "text formats only", etc.
The downside of tying this metadata to the style
is that it would not enforce those limitations at validation time. Whereas with things like min
and max
and stepSize
those requirements can be enforced beyond the widget level.
Validation in general could certainly use some improvement in the framework; see scijava/scijava-common#47 for details.
In particular, it would be useful if you can provide a java.io.FileFilter
or java.io.FileNameFilter
. For scripting in particular, we might provide shortcuts for org.apache.commons.io.filefilter.WildcardFilter
and org.apache.commons.io.filefilter.RegexFileFilter
.
Do we have to change FileWidget
to account for this? Or rather parse the style
annotation, split it at :
and then create a filter?
For example:
style="open:*.xls;*.xlsx"
=> new WildcardFilter({"*.xls", "*.xlsx"})
style="open:/.*\.(xls|xlsx)/
=> new RegexFileFilter(/.*\.(xls|xlsx)/)
Also, we should consider whether this filter restricts the allowed files, or we use it simply to facilitate file choice by offering multiple filter types in the "File of Type" dropdown for JFileChooser
.
With https://github.com/scijava/scijava-ui-swing/commit/73281ecafabaef8e4eee2a75bda339e90cf86507 (see also https://github.com/scijava/scijava-ui-swing/pull/27), filtering by file extension is now possible with the following syntax:
#@ File (style = "open, extensions:xls/xlsx") inputFile
So this is implemented at the UI level. If at some point we want to restrict file types at the scijava-common
level, we should re-open this issue.
I am not exactly sure what you mean by implemented at the UI level, but following this forum post I reopen the issue.
It seems that trying to use style="extensions:png/jpg"
as depicted on the wiki page for script parameters, does not work with single #@File
input.
Seeing my comment above, this must have worked at the time of writing. If it doesn't now, it's a regression.
I'll reopen the issue.
I dug in the code a bit, I could find only one place in the SwingFileListWidget
class where the chooseFiles
method supposed to do the file filtering based on extensions (as far as understood) is called.
However there is no case above this line for a style
that would mention specific file extensions, only the file/directory style options, is that where the missing bit is ?
The filter is derived from the widgetStyle
parameter here, and then handed over to the chooseFiles()
method.
As I wrote above, it was working at the time when we implemented and tested it.
It might be that some changes in the framework broke the functionality in some situations, though. We'll have to test all of these:
-
#@ File (style="extensions:png/jpg") f
as a single parameter (supposed to open a file chooser dialog directly) -
#@ File (style="extensions:png/jpg") f
together with other parameters (supposed to create aFileWidget
) -
#@ File[] (style="extensions:png/jpg") files
as a single parameter (supposed to open a (multiple) file chooser dialog directly) -
#@ File[] (style="extensions:png/jpg") files
together with other parameters (supposed to create aFileListWidget
)
While testing for extensions, I also noticed that
#@ File[] (style="directory") dirs
print dirs
As a single parameter does not seem to have the expected behaviour, it still allows the selection of files.
However with other parameters, using the Add Folder content
button correctly return only folders entries for the selected folder.
The single-file widget works as expected.
EDIT : My fault, it works, just using directories
and not directory
EDIT2: I guess we could make the File array also work with directory
as style
.
Replacing
} else if (widgetModel.isStyle(FileListWidget.DIRECTORIES_ONLY))
by
} else if (widgetModel.isStyle(FileListWidget.DIRECTORIES_ONLY)) || (widgetModel.isStyle(FileWidget.DIRECTORY_STYLE))
at this line
Thanks @LauLauThom for testing.
Note that the style
attribute also has some other flaws currently: https://github.com/scijava/scijava-common/issues/333 I just never got around to tackle these in a robust way (with adding tests etc.), and it seems nobody else had free resources to do this either.
we could make the File array also work with
directory
asstyle
Do we really want to allow this? It feels to me like being tolerant of typos and also allowing fyles
, flies
, oven
, safe
etc.
Everything we allow here will have to be supported (and maintained) forever.