*
* The MIT License (MIT)
*
- * Copyright (C) 2017 Kevin Lamonte
+ * Copyright (C) 2019 Kevin Lamonte
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
import java.io.File;
import java.io.IOException;
+import java.util.List;
+import java.util.ResourceBundle;
+import jexer.backend.SwingTerminal;
import jexer.bits.GraphicsChars;
import jexer.event.TKeypressEvent;
+import jexer.ttree.TDirectoryTreeItem;
+import jexer.ttree.TTreeItem;
+import jexer.ttree.TTreeViewWidget;
import static jexer.TKeypress.*;
/**
* TFileOpenBox is a system-modal dialog for selecting a file to open. Call
* it like:
*
- * <p>
* <pre>
* {@code
* filename = application.fileOpenBox("/path/to/file.ext",
* </pre>
*
*/
-public final class TFileOpenBox extends TWindow {
+public class TFileOpenBox extends TWindow {
+
+ /**
+ * Translated strings.
+ */
+ private static final ResourceBundle i18n = ResourceBundle.getBundle(TFileOpenBox.class.getName());
+
+ // ------------------------------------------------------------------------
+ // Constants --------------------------------------------------------------
+ // ------------------------------------------------------------------------
/**
* TFileOpenBox can be called for either Open or Save actions.
/**
* Button will be labeled "Save".
*/
- SAVE
+ SAVE,
+
+ /**
+ * Button will be labeled "Select".
+ */
+ SELECT
}
+ // ------------------------------------------------------------------------
+ // Variables --------------------------------------------------------------
+ // ------------------------------------------------------------------------
+
/**
* String to return, or null if the user canceled.
*/
private String filename = null;
- /**
- * Get the return string.
- *
- * @return the filename the user selected, or null if they canceled.
- */
- public String getFilename() {
- return filename;
- }
-
/**
* The left-side tree view pane.
*/
- private TTreeView treeView;
+ private TTreeViewWidget treeView;
/**
* The data behind treeView.
private TButton openButton;
/**
- * See if there is a valid filename to return. If the filename is a
- * directory, then
+ * The type of box this is (OPEN, SAVE, or SELECT).
+ */
+ private Type type = Type.OPEN;
+
+ // ------------------------------------------------------------------------
+ // Constructors -----------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ /**
+ * Public constructor. The file open box will be centered on screen.
*
- * @param newFilename the filename to check and return
+ * @param application the TApplication that manages this window
+ * @param path path of selected file
+ * @param type one of the Type constants
* @throws IOException of a java.io operation throws
*/
- private void checkFilename(final String newFilename) throws IOException {
- File newFile = new File(newFilename);
- if (newFile.exists()) {
- if (newFile.isFile()) {
- filename = newFilename;
- getApplication().closeWindow(this);
- return;
- }
- if (newFile.isDirectory()) {
- treeViewRoot = new TDirectoryTreeItem(treeView, newFilename,
- true);
- treeView.setTreeRoot(treeViewRoot, true);
- treeView.reflowData();
- openButton.setEnabled(false);
- directoryList.setPath(newFilename);
- }
- }
+ public TFileOpenBox(final TApplication application, final String path,
+ final Type type) throws IOException {
+
+ this(application, path, type, null);
}
/**
* @param application the TApplication that manages this window
* @param path path of selected file
* @param type one of the Type constants
+ * @param filters a list of strings that files must match to be displayed
* @throws IOException of a java.io operation throws
*/
public TFileOpenBox(final TApplication application, final String path,
- final Type type) throws IOException {
+ final Type type, final List<String> filters) throws IOException {
// Register with the TApplication
super(application, "", 0, 0, 76, 22, MODAL);
try {
checkFilename(entryField.getText());
} catch (IOException e) {
- e.printStackTrace();
+ // If the backend is Swing, we can emit the stack
+ // trace to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
}
}
}, null);
entryField.onKeypress(new TKeypressEvent(kbEnd));
// Add directory treeView
- treeView = addTreeView(1, 3, 30, getHeight() - 6,
+ treeView = addTreeViewWidget(1, 3, 30, getHeight() - 6,
new TAction() {
public void DO() {
TTreeItem item = treeView.getSelected();
File selectedDir = ((TDirectoryTreeItem) item).getFile();
try {
directoryList.setPath(selectedDir.getCanonicalPath());
- openButton.setEnabled(false);
- activate(directoryList);
+ entryField.setText(selectedDir.getCanonicalPath());
+ if (type == Type.OPEN) {
+ openButton.setEnabled(false);
+ }
+ activate(treeView);
} catch (IOException e) {
- e.printStackTrace();
+ // If the backend is Swing, we can emit the stack
+ // trace to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
}
}
}
// Add directory files list
directoryList = addDirectoryList(path, 34, 3, 28, getHeight() - 6,
+ new TAction() {
+ public void DO() {
+ try {
+ File newPath = directoryList.getPath();
+ entryField.setText(newPath.getCanonicalPath());
+ entryField.onKeypress(new TKeypressEvent(kbEnd));
+ openButton.setEnabled(true);
+ activate(entryField);
+ checkFilename(entryField.getText());
+ } catch (IOException e) {
+ // If the backend is Swing, we can emit the stack
+ // trace to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
+ }
+ }
+ },
new TAction() {
public void DO() {
try {
openButton.setEnabled(true);
activate(entryField);
} catch (IOException e) {
- e.printStackTrace();
+ // If the backend is Swing, we can emit the stack
+ // trace to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
}
}
- }
- );
+ },
+ filters);
String openLabel = "";
switch (type) {
case OPEN:
- openLabel = " &Open ";
- setTitle("Open File...");
+ openLabel = i18n.getString("openButton");
+ setTitle(i18n.getString("openTitle"));
break;
case SAVE:
- openLabel = " &Save ";
- setTitle("Save File...");
+ openLabel = i18n.getString("saveButton");
+ setTitle(i18n.getString("saveTitle"));
+ break;
+ case SELECT:
+ openLabel = i18n.getString("selectButton");
+ setTitle(i18n.getString("selectTitle"));
break;
default:
throw new IllegalArgumentException("Invalid type: " + type);
}
+ this.type = type;
// Setup button actions
openButton = addButton(openLabel, this.getWidth() - 12, 3,
try {
checkFilename(entryField.getText());
} catch (IOException e) {
- e.printStackTrace();
+ // If the backend is Swing, we can emit the stack
+ // trace to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
}
}
}
);
- openButton.setEnabled(false);
+ if (type == Type.OPEN) {
+ openButton.setEnabled(false);
+ }
- addButton("&Cancel", getWidth() - 12, 5,
+ addButton(i18n.getString("cancelButton"), getWidth() - 12, 5,
new TAction() {
public void DO() {
filename = null;
getApplication().yield();
}
- /**
- * Draw me on screen.
- */
- @Override
- public void draw() {
- super.draw();
- getScreen().vLineXY(33, 4, getHeight() - 6, GraphicsChars.WINDOW_SIDE,
- getBackground());
- }
+ // ------------------------------------------------------------------------
+ // Event handlers ---------------------------------------------------------
+ // ------------------------------------------------------------------------
/**
* Handle keystrokes.
return;
}
+ if (treeView.isActive()) {
+ if ((keypress.equals(kbEnter))
+ || (keypress.equals(kbUp))
+ || (keypress.equals(kbDown))
+ || (keypress.equals(kbPgUp))
+ || (keypress.equals(kbPgDn))
+ || (keypress.equals(kbHome))
+ || (keypress.equals(kbEnd))
+ ) {
+ // Tree view will be changing, update the directory list.
+ super.onKeypress(keypress);
+
+ // This is the same action as treeView's enter.
+ TTreeItem item = treeView.getSelected();
+ File selectedDir = ((TDirectoryTreeItem) item).getFile();
+ try {
+ directoryList.setPath(selectedDir.getCanonicalPath());
+ if (type == Type.OPEN) {
+ openButton.setEnabled(false);
+ }
+ activate(treeView);
+ } catch (IOException e) {
+ // If the backend is Swing, we can emit the stack trace
+ // to stderr. Otherwise, just squash it.
+ if (getScreen() instanceof SwingTerminal) {
+ e.printStackTrace();
+ }
+ }
+ return;
+ }
+ }
+
// Pass to my parent
super.onKeypress(keypress);
}
+ // ------------------------------------------------------------------------
+ // TWidget ----------------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ /**
+ * Draw me on screen.
+ */
+ @Override
+ public void draw() {
+ super.draw();
+ vLineXY(33, 4, getHeight() - 6, GraphicsChars.WINDOW_SIDE,
+ getBackground());
+ }
+
+ // ------------------------------------------------------------------------
+ // TFileOpenBox -----------------------------------------------------------
+ // ------------------------------------------------------------------------
+
+ /**
+ * Get the return string.
+ *
+ * @return the filename the user selected, or null if they canceled.
+ */
+ public String getFilename() {
+ return filename;
+ }
+
+ /**
+ * See if there is a valid filename to return. If the filename is a
+ * directory, then
+ *
+ * @param newFilename the filename to check and return
+ * @throws IOException of a java.io operation throws
+ */
+ private void checkFilename(final String newFilename) throws IOException {
+ File newFile = new File(newFilename);
+ if (newFile.exists()) {
+ if (newFile.isFile() || (type == Type.SELECT)) {
+ filename = newFilename;
+ getApplication().closeWindow(this);
+ return;
+ }
+ if (newFile.isDirectory()) {
+ treeViewRoot = new TDirectoryTreeItem(treeView,
+ newFilename, true);
+ treeView.setTreeRoot(treeViewRoot, true);
+ if (type == Type.OPEN) {
+ openButton.setEnabled(false);
+ }
+ directoryList.setPath(newFilename);
+ }
+ } else if (type != Type.OPEN) {
+ filename = newFilename;
+ getApplication().closeWindow(this);
+ return;
+ }
+ }
+
}