stubs for TFileOpenBox, cleanup putStringXY
[fanfix.git] / src / jexer / TFileOpenBox.java
diff --git a/src/jexer/TFileOpenBox.java b/src/jexer/TFileOpenBox.java
new file mode 100644 (file)
index 0000000..eb2c924
--- /dev/null
@@ -0,0 +1,243 @@
+/**
+ * Jexer - Java Text User Interface
+ *
+ * License: LGPLv3 or later
+ *
+ * This module is licensed under the GNU Lesser General Public License
+ * Version 3.  Please see the file "COPYING" in this directory for more
+ * information about the GNU Lesser General Public License Version 3.
+ *
+ *     Copyright (C) 2015  Kevin Lamonte
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see
+ * http://www.gnu.org/licenses/, or write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ * @author Kevin Lamonte [kevin.lamonte@gmail.com]
+ * @version 1
+ */
+package jexer;
+
+import java.io.File;
+import java.io.IOException;
+
+import jexer.bits.GraphicsChars;
+import jexer.event.TKeypressEvent;
+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",
+ *         TFileOpenBox.Type.OPEN);
+ *     if (filename != null) {
+ *         ... the user selected a file, go open it ...
+ *     }
+ * }
+ * </pre>
+ *
+ */
+public final class TFileOpenBox extends TWindow {
+
+    /**
+     * TFileOpenBox can be called for either Open or Save actions.
+     */
+    public enum Type {
+        OPEN,
+        SAVE
+    }
+
+    /**
+     * 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;
+
+    /**
+     * The data behind treeView.
+     */
+    private TDirectoryTreeItem treeViewRoot;
+
+    /**
+     * The right-side directory list pane.
+     */
+    @SuppressWarnings("unused")
+    private TDirectoryList directoryList;
+
+    /**
+     * The top row text field.
+     */
+    private TField entryField;
+
+    /**
+     * The Open or Save button.
+     */
+    private TButton openButton;
+
+    /**
+     * Update the fields in response to other field updates.
+     *
+     * @param enter if true, the user manually entered a filename
+     */
+    @SuppressWarnings("unused")
+    private void onUpdate(boolean enter) throws IOException {
+        String newFilename = entryField.getText();
+        File newFile = new File(newFilename);
+        if (newFile.exists()) {
+            if (enter) {
+                if (newFile.isFile()) {
+                    filename = entryField.getText();
+                    getApplication().closeWindow(this);
+                }
+                if (newFile.isDirectory()) {
+                    treeViewRoot = new TDirectoryTreeItem(treeView,
+                        entryField.getText(), true);
+                    treeView.setTreeRoot(treeViewRoot, true);
+                    treeView.reflow();
+                }
+                openButton.setEnabled(false);
+            } else {
+                if (newFile.isFile()) {
+                    openButton.setEnabled(true);
+                } else {
+                    openButton.setEnabled(false);
+                }
+            }
+        } else {
+            openButton.setEnabled(false);
+        }
+    }
+
+    /**
+     * Public constructor.  The file open box will be centered on screen.
+     *
+     * @param application the TApplication that manages this window
+     * @param path path of selected file
+     * @param type one of the Type constants
+     */
+    public TFileOpenBox(final TApplication application, final String path,
+        final Type type) throws IOException {
+
+        // Register with the TApplication
+        super(application, "", 0, 0, 76, 22, MODAL);
+
+        // Add text field
+        entryField = addField(1, 1, getWidth() - 4, false,
+            (new File(path)).getCanonicalPath(),
+            new TAction() {
+                public void DO() {}
+            }, null);
+
+        // Add directory treeView
+        treeView = addTreeView(1, 3, 30, getHeight() - 6,
+            new TAction() {
+                public void DO() {}
+            }
+        );
+        treeViewRoot = new TDirectoryTreeItem(treeView, path, true);
+
+        // Add directory files list
+        directoryList = addDirectoryList(path, 34, 3, 28, getHeight() - 6,
+            new TAction() {
+                public void DO() {}
+            }
+        );
+
+        String openLabel = "";
+        switch (type) {
+        case OPEN:
+            openLabel = " &Open ";
+            setTitle("Open File...");
+            break;
+        case SAVE:
+            openLabel = " &Save ";
+            setTitle("Save File...");
+            break;
+        default:
+            throw new IllegalArgumentException("Invalid type: " + type);
+        }
+
+        // Setup button actions
+        openButton = addButton(openLabel, this.getWidth() - 12, 3,
+            new TAction() {
+                public void DO() {}
+            }
+        );
+        openButton.setEnabled(false);
+
+        addButton("&Cancel", getWidth() - 12, 5,
+            new TAction() {
+                public void DO() {
+                    filename = null;
+                    getApplication().closeWindow(TFileOpenBox.this);
+                }
+            }
+        );
+
+        // Set the secondaryFiber to run me
+        getApplication().enableSecondaryEventReceiver(this);
+
+        // Yield to the secondary thread.  When I come back from the
+        // constructor response will already be set.
+        getApplication().yield();
+    }
+
+    /**
+     * Draw me on screen.
+     */
+    @Override
+    public void draw() {
+        super.draw();
+        getScreen().vLineXY(33, 4, getHeight() - 6, GraphicsChars.WINDOW_SIDE,
+            getBackground());
+    }
+
+    /**
+     * Handle keystrokes.
+     *
+     * @param keypress keystroke event
+     */
+    @Override
+    public void onKeypress(final TKeypressEvent keypress) {
+        // Escape - behave like cancel
+        if (keypress.equals(kbEsc)) {
+            // Close window
+            filename = null;
+            getApplication().closeWindow(this);
+            return;
+        }
+
+        // Pass to my parent
+        super.onKeypress(keypress);
+    }
+
+}