Commit | Line | Data |
---|---|---|
7668cb45 KL |
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; | |
0d47c546 | 34 | import java.io.IOException; |
7668cb45 KL |
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 | /** | |
a043164f | 45 | * File corresponding to this list item. |
7668cb45 | 46 | */ |
a043164f KL |
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 | } | |
7668cb45 KL |
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 void onExpand() { | |
a043164f | 64 | // System.err.printf("onExpand() %s\n", file); |
0d47c546 | 65 | |
a043164f | 66 | if (file == null) { |
7668cb45 KL |
67 | return; |
68 | } | |
69 | getChildren().clear(); | |
70 | ||
71 | // Make sure we can read it before trying to. | |
a043164f | 72 | if (file.canRead()) { |
7668cb45 KL |
73 | setSelectable(true); |
74 | } else { | |
75 | setSelectable(false); | |
76 | } | |
a043164f | 77 | assert (file.isDirectory()); |
7668cb45 KL |
78 | setExpandable(true); |
79 | ||
80 | if ((isExpanded() == false) || (isExpandable() == false)) { | |
81 | getTreeView().reflow(); | |
82 | return; | |
83 | } | |
84 | ||
a043164f | 85 | for (File f: file.listFiles()) { |
0d47c546 KL |
86 | // System.err.printf(" -> file %s %s\n", file, file.getName()); |
87 | ||
a043164f | 88 | if (f.getName().startsWith(".")) { |
0d47c546 | 89 | // Hide dot-files |
7668cb45 KL |
90 | continue; |
91 | } | |
a043164f | 92 | if (!f.isDirectory()) { |
7668cb45 KL |
93 | continue; |
94 | } | |
95 | ||
0d47c546 KL |
96 | try { |
97 | TDirectoryTreeItem item = new TDirectoryTreeItem(getTreeView(), | |
a043164f | 98 | f.getCanonicalPath(), false, false); |
7668cb45 | 99 | |
0d47c546 KL |
100 | item.level = this.level + 1; |
101 | getChildren().add(item); | |
102 | } catch (IOException e) { | |
103 | continue; | |
104 | } | |
7668cb45 KL |
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, final boolean expanded) { | |
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 | */ | |
0d47c546 KL |
131 | public TDirectoryTreeItem(final TTreeView view, |
132 | final String text) throws IOException { | |
133 | ||
7668cb45 KL |
134 | this(view, text, false, true); |
135 | } | |
136 | ||
137 | /** | |
138 | * Public constructor. | |
139 | * | |
140 | * @param view root TTreeView | |
141 | * @param text text for this item | |
142 | * @param expanded if true, have it expanded immediately | |
143 | */ | |
144 | public TDirectoryTreeItem(final TTreeView view, final String text, | |
0d47c546 | 145 | final boolean expanded) throws IOException { |
7668cb45 KL |
146 | |
147 | this(view, text, expanded, true); | |
148 | } | |
149 | ||
150 | /** | |
151 | * Public constructor. | |
152 | * | |
153 | * @param view root TTreeView | |
154 | * @param text text for this item | |
155 | * @param expanded if true, have it expanded immediately | |
156 | * @param openParents if true, expand all paths up the root path and | |
157 | * return the root path entry | |
158 | */ | |
159 | public TDirectoryTreeItem(final TTreeView view, final String text, | |
0d47c546 | 160 | final boolean expanded, final boolean openParents) throws IOException { |
7668cb45 KL |
161 | |
162 | super(view, text, false); | |
163 | ||
a043164f | 164 | List<String> parentFiles = new LinkedList<String>(); |
7668cb45 KL |
165 | boolean oldExpanded = expanded; |
166 | ||
0d47c546 | 167 | // Convert to canonical path |
a043164f KL |
168 | File rootFile = new File(text); |
169 | rootFile = rootFile.getCanonicalFile(); | |
0d47c546 | 170 | |
7668cb45 KL |
171 | if (openParents == true) { |
172 | setExpanded(true); | |
173 | ||
174 | // Go up the directory tree | |
a043164f | 175 | File parent = rootFile.getParentFile(); |
7668cb45 | 176 | while (parent != null) { |
a043164f KL |
177 | parentFiles.add(rootFile.getName()); |
178 | rootFile = rootFile.getParentFile(); | |
179 | parent = rootFile.getParentFile(); | |
7668cb45 | 180 | } |
0d47c546 | 181 | } |
a043164f KL |
182 | file = rootFile; |
183 | if (rootFile.getParentFile() == null) { | |
0d47c546 | 184 | // This is a filesystem root, use its full name |
a043164f | 185 | setText(rootFile.getCanonicalPath()); |
7668cb45 | 186 | } else { |
0d47c546 KL |
187 | // This is a relative path. We got here because openParents was |
188 | // false. | |
189 | assert (openParents == false); | |
a043164f | 190 | setText(rootFile.getName()); |
7668cb45 | 191 | } |
7668cb45 KL |
192 | onExpand(); |
193 | ||
194 | if (openParents == true) { | |
a043164f KL |
195 | TDirectoryTreeItem childFile = this; |
196 | Collections.reverse(parentFiles); | |
197 | for (String p: parentFiles) { | |
198 | for (TWidget widget: childFile.getChildren()) { | |
7668cb45 KL |
199 | TDirectoryTreeItem child = (TDirectoryTreeItem) widget; |
200 | if (child.getText().equals(p)) { | |
a043164f KL |
201 | childFile = child; |
202 | childFile.setExpanded(true); | |
203 | childFile.onExpand(); | |
7668cb45 KL |
204 | break; |
205 | } | |
206 | } | |
207 | } | |
208 | unselect(); | |
a043164f | 209 | getTreeView().setSelected(childFile); |
7668cb45 KL |
210 | setExpanded(oldExpanded); |
211 | } | |
212 | getTreeView().reflow(); | |
213 | } | |
214 | } |