Merge branch 'subtree'
[fanfix.git] / src / jexer / TDirectoryList.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2019 Kevin Lamonte
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer;
30
31 import java.io.File;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 import jexer.bits.StringUtils;
38
39 /**
40 * TDirectoryList shows the files within a directory.
41 */
42 public class TDirectoryList extends TList {
43
44 // ------------------------------------------------------------------------
45 // Variables --------------------------------------------------------------
46 // ------------------------------------------------------------------------
47
48 /**
49 * Files in the directory.
50 */
51 private Map<String, File> files;
52
53 /**
54 * Root path containing files to display.
55 */
56 private File path;
57
58 /**
59 * The list of filters that a file must match in order to be displayed.
60 */
61 private List<String> filters;
62
63 // ------------------------------------------------------------------------
64 // Constructors -----------------------------------------------------------
65 // ------------------------------------------------------------------------
66
67 /**
68 * Public constructor.
69 *
70 * @param parent parent widget
71 * @param path directory path, must be a directory
72 * @param x column relative to parent
73 * @param y row relative to parent
74 * @param width width of text area
75 * @param height height of text area
76 */
77 public TDirectoryList(final TWidget parent, final String path, final int x,
78 final int y, final int width, final int height) {
79
80 this(parent, path, x, y, width, height, null, null, null);
81 }
82
83 /**
84 * Public constructor.
85 *
86 * @param parent parent widget
87 * @param path directory path, must be a directory
88 * @param x column relative to parent
89 * @param y row relative to parent
90 * @param width width of text area
91 * @param height height of text area
92 * @param action action to perform when an item is selected (enter or
93 * double-click)
94 */
95 public TDirectoryList(final TWidget parent, final String path, final int x,
96 final int y, final int width, final int height, final TAction action) {
97
98 this(parent, path, x, y, width, height, action, null, null);
99 }
100
101 /**
102 * Public constructor.
103 *
104 * @param parent parent widget
105 * @param path directory path, must be a directory
106 * @param x column relative to parent
107 * @param y row relative to parent
108 * @param width width of text area
109 * @param height height of text area
110 * @param action action to perform when an item is selected (enter or
111 * double-click)
112 * @param singleClickAction action to perform when an item is selected
113 * (single-click)
114 */
115 public TDirectoryList(final TWidget parent, final String path, final int x,
116 final int y, final int width, final int height, final TAction action,
117 final TAction singleClickAction) {
118
119 this(parent, path, x, y, width, height, action, singleClickAction,
120 null);
121 }
122
123 /**
124 * Public constructor.
125 *
126 * @param parent parent widget
127 * @param path directory path, must be a directory
128 * @param x column relative to parent
129 * @param y row relative to parent
130 * @param width width of text area
131 * @param height height of text area
132 * @param action action to perform when an item is selected (enter or
133 * double-click)
134 * @param singleClickAction action to perform when an item is selected
135 * (single-click)
136 * @param filters a list of strings that files must match to be displayed
137 */
138 public TDirectoryList(final TWidget parent, final String path, final int x,
139 final int y, final int width, final int height, final TAction action,
140 final TAction singleClickAction, final List<String> filters) {
141
142 super(parent, null, x, y, width, height, action);
143 files = new HashMap<String, File>();
144 this.filters = filters;
145 this.singleClickAction = singleClickAction;
146
147 setPath(path);
148 }
149
150 // ------------------------------------------------------------------------
151 // TList ------------------------------------------------------------------
152 // ------------------------------------------------------------------------
153
154 // ------------------------------------------------------------------------
155 // TDirectoryList ---------------------------------------------------------
156 // ------------------------------------------------------------------------
157
158 /**
159 * Set the new path to display.
160 *
161 * @param path new path to list files for
162 */
163 public void setPath(final String path) {
164 this.path = new File(path);
165
166 List<String> newStrings = new ArrayList<String>();
167 files.clear();
168
169 // Build a list of files in this directory
170 File [] newFiles = this.path.listFiles();
171 if (newFiles != null) {
172 for (int i = 0; i < newFiles.length; i++) {
173 if (newFiles[i].getName().startsWith(".")) {
174 continue;
175 }
176 if (newFiles[i].isDirectory()) {
177 continue;
178 }
179 if (filters != null) {
180 for (String pattern: filters) {
181
182 /*
183 System.err.println("newFiles[i] " +
184 newFiles[i].getName() + " " + pattern +
185 " " + newFiles[i].getName().matches(pattern));
186 */
187
188 if (newFiles[i].getName().matches(pattern)) {
189 String key = renderFile(newFiles[i]);
190 files.put(key, newFiles[i]);
191 newStrings.add(key);
192 break;
193 }
194 }
195 } else {
196 String key = renderFile(newFiles[i]);
197 files.put(key, newFiles[i]);
198 newStrings.add(key);
199 }
200 }
201 }
202 setList(newStrings);
203
204 // Select the first entry
205 if (getMaxSelectedIndex() >= 0) {
206 setSelectedIndex(0);
207 }
208 }
209
210 /**
211 * Get the path that is being displayed.
212 *
213 * @return the path
214 */
215 public File getPath() {
216 path = files.get(getSelected());
217 return path;
218 }
219
220 /**
221 * Format one of the entries for drawing on the screen.
222 *
223 * @param file the File
224 * @return the line to draw
225 */
226 private String renderFile(final File file) {
227 String name = file.getName();
228 if (StringUtils.width(name) > 20) {
229 name = name.substring(0, 17) + "...";
230 }
231 return String.format("%-20s %5dk", name, (file.length() / 1024));
232 }
233
234 }