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