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