Commit | Line | Data |
---|---|---|
daa4106c | 1 | /* |
7668cb45 KL |
2 | * Jexer - Java Text User Interface |
3 | * | |
e16dda65 | 4 | * The MIT License (MIT) |
7668cb45 | 5 | * |
a69ed767 | 6 | * Copyright (C) 2019 Kevin Lamonte |
7668cb45 | 7 | * |
e16dda65 KL |
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: | |
7668cb45 | 14 | * |
e16dda65 KL |
15 | * The above copyright notice and this permission notice shall be included in |
16 | * all copies or substantial portions of the Software. | |
7668cb45 | 17 | * |
e16dda65 KL |
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. | |
7668cb45 KL |
25 | * |
26 | * @author Kevin Lamonte [kevin.lamonte@gmail.com] | |
27 | * @version 1 | |
28 | */ | |
d36057df | 29 | package jexer.ttree; |
7668cb45 KL |
30 | |
31 | import java.io.File; | |
0d47c546 | 32 | import java.io.IOException; |
7668cb45 KL |
33 | import java.util.Collections; |
34 | import java.util.List; | |
35 | import java.util.LinkedList; | |
36 | ||
d36057df | 37 | import jexer.TWidget; |
d36057df | 38 | |
7668cb45 KL |
39 | /** |
40 | * TDirectoryTreeItem is a single item in a disk directory tree view. | |
41 | */ | |
42 | public class TDirectoryTreeItem extends TTreeItem { | |
43 | ||
d36057df KL |
44 | // ------------------------------------------------------------------------ |
45 | // Variables -------------------------------------------------------------- | |
46 | // ------------------------------------------------------------------------ | |
47 | ||
7668cb45 | 48 | /** |
a043164f | 49 | * File corresponding to this list item. |
7668cb45 | 50 | */ |
a043164f KL |
51 | private File file; |
52 | ||
53 | /** | |
d36057df | 54 | * The TTreeViewWidget containing this directory tree. |
a043164f | 55 | */ |
d36057df | 56 | private TTreeViewWidget treeViewWidget; |
7668cb45 | 57 | |
d36057df KL |
58 | // ------------------------------------------------------------------------ |
59 | // Constructors ----------------------------------------------------------- | |
60 | // ------------------------------------------------------------------------ | |
7668cb45 KL |
61 | |
62 | /** | |
63 | * Public constructor. | |
64 | * | |
d36057df | 65 | * @param view root TTreeViewWidget |
7668cb45 KL |
66 | * @param text text for this item |
67 | * @param expanded if true, have it expanded immediately | |
329fd62e | 68 | * @throws IOException if a java.io operation throws |
7668cb45 | 69 | */ |
d36057df | 70 | public TDirectoryTreeItem(final TTreeViewWidget view, final String text, |
0d47c546 | 71 | final boolean expanded) throws IOException { |
7668cb45 KL |
72 | |
73 | this(view, text, expanded, true); | |
74 | } | |
75 | ||
76 | /** | |
77 | * Public constructor. | |
78 | * | |
d36057df | 79 | * @param view root TTreeViewWidget |
7668cb45 KL |
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 | |
329fd62e | 84 | * @throws IOException if a java.io operation throws |
7668cb45 | 85 | */ |
d36057df | 86 | public TDirectoryTreeItem(final TTreeViewWidget view, final String text, |
0d47c546 | 87 | final boolean expanded, final boolean openParents) throws IOException { |
7668cb45 | 88 | |
d36057df KL |
89 | super(view.getTreeView(), text, false); |
90 | ||
91 | this.treeViewWidget = view; | |
7668cb45 | 92 | |
a043164f | 93 | List<String> parentFiles = new LinkedList<String>(); |
7668cb45 KL |
94 | boolean oldExpanded = expanded; |
95 | ||
0d47c546 | 96 | // Convert to canonical path |
a043164f KL |
97 | File rootFile = new File(text); |
98 | rootFile = rootFile.getCanonicalFile(); | |
0d47c546 | 99 | |
329fd62e | 100 | if (openParents) { |
7668cb45 KL |
101 | setExpanded(true); |
102 | ||
103 | // Go up the directory tree | |
a043164f | 104 | File parent = rootFile.getParentFile(); |
7668cb45 | 105 | while (parent != null) { |
a043164f KL |
106 | parentFiles.add(rootFile.getName()); |
107 | rootFile = rootFile.getParentFile(); | |
108 | parent = rootFile.getParentFile(); | |
7668cb45 | 109 | } |
0d47c546 | 110 | } |
a043164f KL |
111 | file = rootFile; |
112 | if (rootFile.getParentFile() == null) { | |
0d47c546 | 113 | // This is a filesystem root, use its full name |
a043164f | 114 | setText(rootFile.getCanonicalPath()); |
7668cb45 | 115 | } else { |
0d47c546 KL |
116 | // This is a relative path. We got here because openParents was |
117 | // false. | |
329fd62e | 118 | assert (!openParents); |
a043164f | 119 | setText(rootFile.getName()); |
7668cb45 | 120 | } |
7668cb45 KL |
121 | onExpand(); |
122 | ||
329fd62e | 123 | if (openParents) { |
a043164f KL |
124 | TDirectoryTreeItem childFile = this; |
125 | Collections.reverse(parentFiles); | |
126 | for (String p: parentFiles) { | |
127 | for (TWidget widget: childFile.getChildren()) { | |
7668cb45 KL |
128 | TDirectoryTreeItem child = (TDirectoryTreeItem) widget; |
129 | if (child.getText().equals(p)) { | |
a043164f KL |
130 | childFile = child; |
131 | childFile.setExpanded(true); | |
132 | childFile.onExpand(); | |
7668cb45 KL |
133 | break; |
134 | } | |
135 | } | |
136 | } | |
137 | unselect(); | |
d36057df | 138 | getTreeView().setSelected(childFile, true); |
7668cb45 KL |
139 | setExpanded(oldExpanded); |
140 | } | |
d36057df KL |
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 | ||
270691b6 KL |
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 | } | |
d36057df | 196 | |
270691b6 KL |
197 | try { |
198 | TDirectoryTreeItem item = new TDirectoryTreeItem(treeViewWidget, | |
199 | f.getCanonicalPath(), false, false); | |
d36057df | 200 | |
270691b6 KL |
201 | item.level = this.level + 1; |
202 | getChildren().add(item); | |
203 | } catch (IOException e) { | |
204 | continue; | |
205 | } | |
d36057df KL |
206 | } |
207 | } | |
208 | Collections.sort(getChildren()); | |
7668cb45 | 209 | } |
d36057df | 210 | |
7668cb45 | 211 | } |