2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
32 import java
.io
.IOException
;
34 import jexer
.bits
.GraphicsChars
;
35 import jexer
.event
.TKeypressEvent
;
36 import static jexer
.TKeypress
.*;
39 * TFileOpenBox is a system-modal dialog for selecting a file to open. Call
45 * filename = application.fileOpenBox("/path/to/file.ext",
46 * TFileOpenBox.Type.OPEN);
47 * if (filename != null) {
48 * ... the user selected a file, go open it ...
54 public final class TFileOpenBox
extends TWindow
{
57 * TFileOpenBox can be called for either Open or Save actions.
61 * Button will be labeled "Open".
66 * Button will be labeled "Save".
72 * String to return, or null if the user canceled.
74 private String filename
= null;
77 * Get the return string.
79 * @return the filename the user selected, or null if they canceled.
81 public String
getFilename() {
86 * The left-side tree view pane.
88 private TTreeView treeView
;
91 * The data behind treeView.
93 private TDirectoryTreeItem treeViewRoot
;
96 * The right-side directory list pane.
98 private TDirectoryList directoryList
;
101 * The top row text field.
103 private TField entryField
;
106 * The Open or Save button.
108 private TButton openButton
;
111 * See if there is a valid filename to return. If the filename is a
114 * @param newFilename the filename to check and return
115 * @throws IOException of a java.io operation throws
117 private void checkFilename(final String newFilename
) throws IOException
{
118 File newFile
= new File(newFilename
);
119 if (newFile
.exists()) {
120 if (newFile
.isFile()) {
121 filename
= newFilename
;
122 getApplication().closeWindow(this);
125 if (newFile
.isDirectory()) {
126 treeViewRoot
= new TDirectoryTreeItem(treeView
, newFilename
,
128 treeView
.setTreeRoot(treeViewRoot
, true);
129 treeView
.reflowData();
130 openButton
.setEnabled(false);
131 directoryList
.setPath(newFilename
);
137 * Public constructor. The file open box will be centered on screen.
139 * @param application the TApplication that manages this window
140 * @param path path of selected file
141 * @param type one of the Type constants
142 * @throws IOException of a java.io operation throws
144 public TFileOpenBox(final TApplication application
, final String path
,
145 final Type type
) throws IOException
{
147 // Register with the TApplication
148 super(application
, "", 0, 0, 76, 22, MODAL
);
151 entryField
= addField(1, 1, getWidth() - 4, false,
152 (new File(path
)).getCanonicalPath(),
156 checkFilename(entryField
.getText());
157 } catch (IOException e
) {
162 entryField
.onKeypress(new TKeypressEvent(kbEnd
));
164 // Add directory treeView
165 treeView
= addTreeView(1, 3, 30, getHeight() - 6,
168 TTreeItem item
= treeView
.getSelected();
169 File selectedDir
= ((TDirectoryTreeItem
) item
).getFile();
171 directoryList
.setPath(selectedDir
.getCanonicalPath());
172 openButton
.setEnabled(false);
173 activate(directoryList
);
174 } catch (IOException e
) {
180 treeViewRoot
= new TDirectoryTreeItem(treeView
, path
, true);
182 // Add directory files list
183 directoryList
= addDirectoryList(path
, 34, 3, 28, getHeight() - 6,
187 File newPath
= directoryList
.getPath();
188 entryField
.setText(newPath
.getCanonicalPath());
189 entryField
.onKeypress(new TKeypressEvent(kbEnd
));
190 openButton
.setEnabled(true);
191 activate(entryField
);
192 } catch (IOException e
) {
199 String openLabel
= "";
202 openLabel
= " &Open ";
203 setTitle("Open File...");
206 openLabel
= " &Save ";
207 setTitle("Save File...");
210 throw new IllegalArgumentException("Invalid type: " + type
);
213 // Setup button actions
214 openButton
= addButton(openLabel
, this.getWidth() - 12, 3,
218 checkFilename(entryField
.getText());
219 } catch (IOException e
) {
225 openButton
.setEnabled(false);
227 addButton("&Cancel", getWidth() - 12, 5,
231 getApplication().closeWindow(TFileOpenBox
.this);
236 // Default to the directory list
237 activate(directoryList
);
239 // Set the secondaryFiber to run me
240 getApplication().enableSecondaryEventReceiver(this);
242 // Yield to the secondary thread. When I come back from the
243 // constructor response will already be set.
244 getApplication().yield();
253 getScreen().vLineXY(33, 4, getHeight() - 6, GraphicsChars
.WINDOW_SIDE
,
260 * @param keypress keystroke event
263 public void onKeypress(final TKeypressEvent keypress
) {
264 // Escape - behave like cancel
265 if (keypress
.equals(kbEsc
)) {
268 getApplication().closeWindow(this);
273 super.onKeypress(keypress
);