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