stubs for TFileOpenBox, cleanup putStringXY
[fanfix.git] / src / jexer / TFileOpenBox.java
1 /**
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31 package jexer;
32
33 import java.io.File;
34 import java.io.IOException;
35
36 import jexer.bits.GraphicsChars;
37 import jexer.event.TKeypressEvent;
38 import static jexer.TKeypress.*;
39
40 /**
41 * TFileOpenBox is a system-modal dialog for selecting a file to open. Call
42 * it like:
43 *
44 * <p>
45 * <pre>
46 * {@code
47 * filename = application.fileOpenBox("/path/to/file.ext",
48 * TFileOpenBox.Type.OPEN);
49 * if (filename != null) {
50 * ... the user selected a file, go open it ...
51 * }
52 * }
53 * </pre>
54 *
55 */
56 public final class TFileOpenBox extends TWindow {
57
58 /**
59 * TFileOpenBox can be called for either Open or Save actions.
60 */
61 public enum Type {
62 OPEN,
63 SAVE
64 }
65
66 /**
67 * String to return, or null if the user canceled.
68 */
69 private String filename = null;
70
71 /**
72 * Get the return string.
73 *
74 * @return the filename the user selected, or null if they canceled.
75 */
76 public String getFilename() {
77 return filename;
78 }
79
80 /**
81 * The left-side tree view pane.
82 */
83 private TTreeView treeView;
84
85 /**
86 * The data behind treeView.
87 */
88 private TDirectoryTreeItem treeViewRoot;
89
90 /**
91 * The right-side directory list pane.
92 */
93 @SuppressWarnings("unused")
94 private TDirectoryList directoryList;
95
96 /**
97 * The top row text field.
98 */
99 private TField entryField;
100
101 /**
102 * The Open or Save button.
103 */
104 private TButton openButton;
105
106 /**
107 * Update the fields in response to other field updates.
108 *
109 * @param enter if true, the user manually entered a filename
110 */
111 @SuppressWarnings("unused")
112 private void onUpdate(boolean enter) throws IOException {
113 String newFilename = entryField.getText();
114 File newFile = new File(newFilename);
115 if (newFile.exists()) {
116 if (enter) {
117 if (newFile.isFile()) {
118 filename = entryField.getText();
119 getApplication().closeWindow(this);
120 }
121 if (newFile.isDirectory()) {
122 treeViewRoot = new TDirectoryTreeItem(treeView,
123 entryField.getText(), true);
124 treeView.setTreeRoot(treeViewRoot, true);
125 treeView.reflow();
126 }
127 openButton.setEnabled(false);
128 } else {
129 if (newFile.isFile()) {
130 openButton.setEnabled(true);
131 } else {
132 openButton.setEnabled(false);
133 }
134 }
135 } else {
136 openButton.setEnabled(false);
137 }
138 }
139
140 /**
141 * Public constructor. The file open box will be centered on screen.
142 *
143 * @param application the TApplication that manages this window
144 * @param path path of selected file
145 * @param type one of the Type constants
146 */
147 public TFileOpenBox(final TApplication application, final String path,
148 final Type type) throws IOException {
149
150 // Register with the TApplication
151 super(application, "", 0, 0, 76, 22, MODAL);
152
153 // Add text field
154 entryField = addField(1, 1, getWidth() - 4, false,
155 (new File(path)).getCanonicalPath(),
156 new TAction() {
157 public void DO() {}
158 }, null);
159
160 // Add directory treeView
161 treeView = addTreeView(1, 3, 30, getHeight() - 6,
162 new TAction() {
163 public void DO() {}
164 }
165 );
166 treeViewRoot = new TDirectoryTreeItem(treeView, path, true);
167
168 // Add directory files list
169 directoryList = addDirectoryList(path, 34, 3, 28, getHeight() - 6,
170 new TAction() {
171 public void DO() {}
172 }
173 );
174
175 String openLabel = "";
176 switch (type) {
177 case OPEN:
178 openLabel = " &Open ";
179 setTitle("Open File...");
180 break;
181 case SAVE:
182 openLabel = " &Save ";
183 setTitle("Save File...");
184 break;
185 default:
186 throw new IllegalArgumentException("Invalid type: " + type);
187 }
188
189 // Setup button actions
190 openButton = addButton(openLabel, this.getWidth() - 12, 3,
191 new TAction() {
192 public void DO() {}
193 }
194 );
195 openButton.setEnabled(false);
196
197 addButton("&Cancel", getWidth() - 12, 5,
198 new TAction() {
199 public void DO() {
200 filename = null;
201 getApplication().closeWindow(TFileOpenBox.this);
202 }
203 }
204 );
205
206 // Set the secondaryFiber to run me
207 getApplication().enableSecondaryEventReceiver(this);
208
209 // Yield to the secondary thread. When I come back from the
210 // constructor response will already be set.
211 getApplication().yield();
212 }
213
214 /**
215 * Draw me on screen.
216 */
217 @Override
218 public void draw() {
219 super.draw();
220 getScreen().vLineXY(33, 4, getHeight() - 6, GraphicsChars.WINDOW_SIDE,
221 getBackground());
222 }
223
224 /**
225 * Handle keystrokes.
226 *
227 * @param keypress keystroke event
228 */
229 @Override
230 public void onKeypress(final TKeypressEvent keypress) {
231 // Escape - behave like cancel
232 if (keypress.equals(kbEsc)) {
233 // Close window
234 filename = null;
235 getApplication().closeWindow(this);
236 return;
237 }
238
239 // Pass to my parent
240 super.onKeypress(keypress);
241 }
242
243 }