scijava-common icon indicating copy to clipboard operation
scijava-common copied to clipboard

Add possibility to filter by file type in FileWidget

Open imagejan opened this issue 9 years ago • 9 comments

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.

imagejan avatar Oct 15 '15 09:10 imagejan

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.

ctrueden avatar Oct 21 '15 16:10 ctrueden

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.

imagejan avatar Jun 28 '17 11:06 imagejan

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.

imagejan avatar Dec 13 '17 08:12 imagejan

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.

LauLauThom avatar Jul 22 '19 07:07 LauLauThom

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.

imagejan avatar Jul 23 '19 21:07 imagejan

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 ?

LauLauThom avatar Apr 16 '20 16:04 LauLauThom

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 a FileWidget)
  • #@ 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 a FileListWidget)

imagejan avatar Apr 24 '20 14:04 imagejan

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

LauLauThom avatar Apr 24 '20 15:04 LauLauThom

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 as style

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.

imagejan avatar Apr 24 '20 20:04 imagejan