LICENSE CHANGED TO MIT
[nikiroo-utils.git] / src / jexer / TDirectoryTreeItem.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2016 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.io.IOException;
33 import java.util.Collections;
34 import java.util.List;
35 import java.util.LinkedList;
36
37 /**
38 * TDirectoryTreeItem is a single item in a disk directory tree view.
39 */
40 public class TDirectoryTreeItem extends TTreeItem {
41
42 /**
43 * File corresponding to this list item.
44 */
45 private File file;
46
47 /**
48 * Get the File corresponding to this list item.
49 *
50 * @return the File
51 */
52 public final File getFile() {
53 return file;
54 }
55
56 /**
57 * Called when this item is expanded or collapsed. this.expanded will be
58 * true if this item was just expanded from a mouse click or keypress.
59 */
60 @Override
61 public final void onExpand() {
62 // System.err.printf("onExpand() %s\n", file);
63
64 if (file == null) {
65 return;
66 }
67 getChildren().clear();
68
69 // Make sure we can read it before trying to.
70 if (file.canRead()) {
71 setSelectable(true);
72 } else {
73 setSelectable(false);
74 }
75 assert (file.isDirectory());
76 setExpandable(true);
77
78 if (!isExpanded() || !isExpandable()) {
79 getTreeView().reflow();
80 return;
81 }
82
83 for (File f: file.listFiles()) {
84 // System.err.printf(" -> file %s %s\n", file, file.getName());
85
86 if (f.getName().startsWith(".")) {
87 // Hide dot-files
88 continue;
89 }
90 if (!f.isDirectory()) {
91 continue;
92 }
93
94 try {
95 TDirectoryTreeItem item = new TDirectoryTreeItem(getTreeView(),
96 f.getCanonicalPath(), false, false);
97
98 item.level = this.level + 1;
99 getChildren().add(item);
100 } catch (IOException e) {
101 continue;
102 }
103 }
104 Collections.sort(getChildren());
105
106 getTreeView().reflow();
107 }
108
109 /**
110 * Add a child item. This method should never be used, it will throw an
111 * IllegalArgumentException every time.
112 *
113 * @param text text for this item
114 * @param expanded if true, have it expanded immediately
115 * @return the new item
116 * @throws IllegalArgumentException if this function is called
117 */
118 @Override
119 public final TTreeItem addChild(final String text,
120 final boolean expanded) throws IllegalArgumentException {
121
122 throw new IllegalArgumentException("Do not call addChild(), use onExpand() instead");
123 }
124
125 /**
126 * Public constructor.
127 *
128 * @param view root TTreeView
129 * @param text text for this item
130 * @throws IOException if a java.io operation throws
131 */
132 public TDirectoryTreeItem(final TTreeView view,
133 final String text) throws IOException {
134
135 this(view, text, false, true);
136 }
137
138 /**
139 * Public constructor.
140 *
141 * @param view root TTreeView
142 * @param text text for this item
143 * @param expanded if true, have it expanded immediately
144 * @throws IOException if a java.io operation throws
145 */
146 public TDirectoryTreeItem(final TTreeView view, final String text,
147 final boolean expanded) throws IOException {
148
149 this(view, text, expanded, true);
150 }
151
152 /**
153 * Public constructor.
154 *
155 * @param view root TTreeView
156 * @param text text for this item
157 * @param expanded if true, have it expanded immediately
158 * @param openParents if true, expand all paths up the root path and
159 * return the root path entry
160 * @throws IOException if a java.io operation throws
161 */
162 public TDirectoryTreeItem(final TTreeView view, final String text,
163 final boolean expanded, final boolean openParents) throws IOException {
164
165 super(view, text, false);
166
167 List<String> parentFiles = new LinkedList<String>();
168 boolean oldExpanded = expanded;
169
170 // Convert to canonical path
171 File rootFile = new File(text);
172 rootFile = rootFile.getCanonicalFile();
173
174 if (openParents) {
175 setExpanded(true);
176
177 // Go up the directory tree
178 File parent = rootFile.getParentFile();
179 while (parent != null) {
180 parentFiles.add(rootFile.getName());
181 rootFile = rootFile.getParentFile();
182 parent = rootFile.getParentFile();
183 }
184 }
185 file = rootFile;
186 if (rootFile.getParentFile() == null) {
187 // This is a filesystem root, use its full name
188 setText(rootFile.getCanonicalPath());
189 } else {
190 // This is a relative path. We got here because openParents was
191 // false.
192 assert (!openParents);
193 setText(rootFile.getName());
194 }
195 onExpand();
196
197 if (openParents) {
198 TDirectoryTreeItem childFile = this;
199 Collections.reverse(parentFiles);
200 for (String p: parentFiles) {
201 for (TWidget widget: childFile.getChildren()) {
202 TDirectoryTreeItem child = (TDirectoryTreeItem) widget;
203 if (child.getText().equals(p)) {
204 childFile = child;
205 childFile.setExpanded(true);
206 childFile.onExpand();
207 break;
208 }
209 }
210 }
211 unselect();
212 getTreeView().setSelected(childFile);
213 setExpanded(oldExpanded);
214 }
215 getTreeView().reflow();
216 }
217 }