#31 fix synchronized error
[fanfix.git] / src / jexer / ttree / TDirectoryTreeItem.java
CommitLineData
daa4106c 1/*
7668cb45
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
7668cb45 5 *
a2018e99 6 * Copyright (C) 2017 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 29package jexer.ttree;
7668cb45
KL
30
31import java.io.File;
0d47c546 32import java.io.IOException;
7668cb45
KL
33import java.util.Collections;
34import java.util.List;
35import java.util.LinkedList;
36
d36057df
KL
37import jexer.TWidget;
38import jexer.ttree.TTreeViewWidget;
39
7668cb45
KL
40/**
41 * TDirectoryTreeItem is a single item in a disk directory tree view.
42 */
43public class TDirectoryTreeItem extends TTreeItem {
44
d36057df
KL
45 // ------------------------------------------------------------------------
46 // Variables --------------------------------------------------------------
47 // ------------------------------------------------------------------------
48
7668cb45 49 /**
a043164f 50 * File corresponding to this list item.
7668cb45 51 */
a043164f
KL
52 private File file;
53
54 /**
d36057df 55 * The TTreeViewWidget containing this directory tree.
a043164f 56 */
d36057df 57 private TTreeViewWidget treeViewWidget;
7668cb45 58
d36057df
KL
59 // ------------------------------------------------------------------------
60 // Constructors -----------------------------------------------------------
61 // ------------------------------------------------------------------------
7668cb45
KL
62
63 /**
64 * Public constructor.
65 *
d36057df 66 * @param view root TTreeViewWidget
7668cb45
KL
67 * @param text text for this item
68 * @param expanded if true, have it expanded immediately
329fd62e 69 * @throws IOException if a java.io operation throws
7668cb45 70 */
d36057df 71 public TDirectoryTreeItem(final TTreeViewWidget view, final String text,
0d47c546 72 final boolean expanded) throws IOException {
7668cb45
KL
73
74 this(view, text, expanded, true);
75 }
76
77 /**
78 * Public constructor.
79 *
d36057df 80 * @param view root TTreeViewWidget
7668cb45
KL
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
329fd62e 85 * @throws IOException if a java.io operation throws
7668cb45 86 */
d36057df 87 public TDirectoryTreeItem(final TTreeViewWidget view, final String text,
0d47c546 88 final boolean expanded, final boolean openParents) throws IOException {
7668cb45 89
d36057df
KL
90 super(view.getTreeView(), text, false);
91
92 this.treeViewWidget = view;
7668cb45 93
a043164f 94 List<String> parentFiles = new LinkedList<String>();
7668cb45
KL
95 boolean oldExpanded = expanded;
96
0d47c546 97 // Convert to canonical path
a043164f
KL
98 File rootFile = new File(text);
99 rootFile = rootFile.getCanonicalFile();
0d47c546 100
329fd62e 101 if (openParents) {
7668cb45
KL
102 setExpanded(true);
103
104 // Go up the directory tree
a043164f 105 File parent = rootFile.getParentFile();
7668cb45 106 while (parent != null) {
a043164f
KL
107 parentFiles.add(rootFile.getName());
108 rootFile = rootFile.getParentFile();
109 parent = rootFile.getParentFile();
7668cb45 110 }
0d47c546 111 }
a043164f
KL
112 file = rootFile;
113 if (rootFile.getParentFile() == null) {
0d47c546 114 // This is a filesystem root, use its full name
a043164f 115 setText(rootFile.getCanonicalPath());
7668cb45 116 } else {
0d47c546
KL
117 // This is a relative path. We got here because openParents was
118 // false.
329fd62e 119 assert (!openParents);
a043164f 120 setText(rootFile.getName());
7668cb45 121 }
7668cb45
KL
122 onExpand();
123
329fd62e 124 if (openParents) {
a043164f
KL
125 TDirectoryTreeItem childFile = this;
126 Collections.reverse(parentFiles);
127 for (String p: parentFiles) {
128 for (TWidget widget: childFile.getChildren()) {
7668cb45
KL
129 TDirectoryTreeItem child = (TDirectoryTreeItem) widget;
130 if (child.getText().equals(p)) {
a043164f
KL
131 childFile = child;
132 childFile.setExpanded(true);
133 childFile.onExpand();
7668cb45
KL
134 break;
135 }
136 }
137 }
138 unselect();
d36057df 139 getTreeView().setSelected(childFile, true);
7668cb45
KL
140 setExpanded(oldExpanded);
141 }
d36057df
KL
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 for (File f: file.listFiles()) {
186 // System.err.printf(" -> file %s %s\n", file, file.getName());
187
188 if (f.getName().startsWith(".")) {
189 // Hide dot-files
190 continue;
191 }
192 if (!f.isDirectory()) {
193 continue;
194 }
195
196 try {
197 TDirectoryTreeItem item = new TDirectoryTreeItem(treeViewWidget,
198 f.getCanonicalPath(), false, false);
199
200 item.level = this.level + 1;
201 getChildren().add(item);
202 } catch (IOException e) {
203 continue;
204 }
205 }
206 Collections.sort(getChildren());
7668cb45 207 }
d36057df 208
7668cb45 209}