Skip to content

Commit 5b10cf4

Browse files
authored
Merge pull request #276 from imagejan/multiple-file-input
Add method signatures and preprocessor to select multiple files
2 parents 9105fdd + baaaa55 commit 5b10cf4

File tree

6 files changed

+138
-2
lines changed

6 files changed

+138
-2
lines changed

src/main/java/org/scijava/module/DefaultModuleService.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ public <T> void save(final ModuleItem<T> item, final T value) {
297297
return;
298298
}
299299

300+
// FIXME: Convert to string, instead of just calling toString.
301+
// Otherwise many things (e.g. File[]) are persisted improperly.
300302
final String sValue = value == null ? "" : value.toString();
301303

302304
// do not persist if object cannot be converted back from a string

src/main/java/org/scijava/ui/DefaultUIService.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
package org.scijava.ui;
3434

3535
import java.io.File;
36+
import java.io.FileFilter;
3637
import java.util.ArrayList;
3738
import java.util.Collections;
3839
import java.util.HashMap;
@@ -319,6 +320,18 @@ public File chooseFile(final File file, final String style) {
319320
return ui == null ? null : ui.chooseFile(title, file, style);
320321
}
321322

323+
@Override
324+
public File[] chooseFiles(File[] files, FileFilter filter) {
325+
final UserInterface ui = getDefaultUI();
326+
return ui == null ? null : ui.chooseFiles(files, filter);
327+
}
328+
329+
@Override
330+
public List<File> chooseFiles(List<File> fileList, FileFilter filter) {
331+
final UserInterface ui = getDefaultUI();
332+
return ui == null ? null : ui.chooseFiles(fileList, filter);
333+
}
334+
322335
@Override
323336
public void showContextMenu(final String menuRoot, final Display<?> display,
324337
final int x, final int y)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package org.scijava.ui;
2+
3+
import java.io.File;
4+
5+
import org.scijava.module.Module;
6+
import org.scijava.module.ModuleItem;
7+
import org.scijava.module.process.AbstractPreprocessorPlugin;
8+
import org.scijava.module.process.PreprocessorPlugin;
9+
import org.scijava.plugin.Parameter;
10+
import org.scijava.plugin.Plugin;
11+
import org.scijava.widget.InputHarvester;
12+
13+
@Plugin(type = PreprocessorPlugin.class, priority = InputHarvester.PRIORITY + 1.0)
14+
public class FileListPreprocessor extends AbstractPreprocessorPlugin {
15+
16+
@Parameter(required = false)
17+
private UIService uiService;
18+
19+
@Override
20+
public void process(final Module module) {
21+
if (uiService == null) return;
22+
final ModuleItem<File[]> fileInput = getFilesInput(module);
23+
if (fileInput == null) return;
24+
25+
final File[] files = fileInput.getValue(module);
26+
27+
// show file chooser dialog box
28+
final File[] result = uiService.chooseFiles(files, null);
29+
if (result == null) {
30+
cancel("");
31+
return;
32+
}
33+
34+
fileInput.setValue(module, result);
35+
module.resolveInput(fileInput.getName());
36+
}
37+
38+
// -- Helper methods --
39+
40+
/**
41+
* Gets the single unresolved {@link File} input parameter. If there is not
42+
* exactly one unresolved {@link File} input parameter, or if there are other
43+
* types of unresolved parameters, this method returns null.
44+
*/
45+
private ModuleItem<File[]> getFilesInput(final Module module) {
46+
ModuleItem<File[]> result = null;
47+
for (final ModuleItem<?> input : module.getInfo().inputs()) {
48+
if (module.isInputResolved(input.getName())) continue;
49+
final Class<?> type = input.getType();
50+
if (!File[].class.isAssignableFrom(type)) {
51+
// not a File[] parameter; abort
52+
return null;
53+
}
54+
if (result != null) {
55+
// second File parameter; abort
56+
return null;
57+
}
58+
@SuppressWarnings("unchecked")
59+
final ModuleItem<File[]> fileInput = (ModuleItem<File[]>) input;
60+
result = fileInput;
61+
}
62+
return result;
63+
}
64+
}

src/main/java/org/scijava/ui/UIService.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
package org.scijava.ui;
3434

3535
import java.io.File;
36+
import java.io.FileFilter;
3637
import java.util.List;
3738

3839
import org.scijava.app.StatusService;
@@ -294,6 +295,28 @@ DialogPrompt.Result showDialog(String message, String title,
294295
*/
295296
File chooseFile(String title, File file, String style);
296297

298+
/**
299+
* Prompts the user to select one or multiple files.
300+
* <p>
301+
* The prompt is displayed in the default user interface.
302+
* </p>
303+
*
304+
* @param files The initial value displayed in the file chooser prompt.
305+
* @param filter A filter allowing to restrict the choice of files
306+
*/
307+
File[] chooseFiles(File[] files, FileFilter filter);
308+
309+
/**
310+
* Prompts the user to select one or multiple files.
311+
* <p>
312+
* The prompt is displayed in the default user interface.
313+
* </p>
314+
*
315+
* @param fileList The initial value displayed in the file chooser prompt.
316+
* @param filter A filter allowing to restrict the choice of files
317+
*/
318+
List<File> chooseFiles(List<File> fileList, FileFilter filter);
319+
297320
/**
298321
* Displays a popup context menu for the given display at the specified
299322
* position.
@@ -309,5 +332,4 @@ DialogPrompt.Result showDialog(String message, String title,
309332
* @see StatusService#getStatusMessage(String, StatusEvent)
310333
*/
311334
String getStatusMessage(StatusEvent statusEvent);
312-
313335
}

src/main/java/org/scijava/ui/UserInterface.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@
3333
package org.scijava.ui;
3434

3535
import java.io.File;
36+
import java.io.FileFilter;
37+
import java.util.Arrays;
38+
import java.util.List;
3639

3740
import org.scijava.Disposable;
3841
import org.scijava.display.Display;
@@ -185,6 +188,32 @@ default File chooseFile(String title, File file, String style) {
185188
throw new UnsupportedOperationException();
186189
}
187190

191+
/**
192+
* Prompts the user to choose a list of files.
193+
*
194+
* @param files The initial value displayed in the file chooser prompt.
195+
* @param filter A filter allowing to restrict file choice.
196+
* @return The selected {@link File}s chosen by the user, or null if the
197+
* user cancels the prompt.
198+
*/
199+
default File[] chooseFiles(File[] files, FileFilter filter) {
200+
throw new UnsupportedOperationException();
201+
}
202+
203+
/**
204+
* Prompts the user to choose a list of files.
205+
*
206+
* @param fileList The initial value displayed in the file chooser prompt.
207+
* @param filter A filter allowing to restrict file choice.
208+
* @return The selected {@link File}s chosen by the user, or null if the
209+
* user cancels the prompt.
210+
*/
211+
default List<File> chooseFiles(List<File> fileList, FileFilter filter) {
212+
final File[] initialFiles = fileList.toArray(new File[fileList.size()]);
213+
final File[] chosenFiles = chooseFiles(initialFiles, filter);
214+
return chosenFiles == null ? null : Arrays.asList(chosenFiles);
215+
}
216+
188217
/**
189218
* Displays a popup context menu for the given display at the specified
190219
* position.
@@ -199,5 +228,4 @@ default File chooseFile(String title, File file, String style) {
199228

200229
/** Returns true if this UI requires the EDT. */
201230
boolean requiresEDT();
202-
203231
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.scijava.widget;
2+
3+
import java.io.File;
4+
5+
public interface FileListWidget<U> extends InputWidget<File[], U> {
6+
// NB: No changes to interface.
7+
}

0 commit comments

Comments
 (0)