#35 Blinking double-width text for tterminal
[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 *
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 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 37import jexer.TWidget;
d36057df 38
7668cb45
KL
39/**
40 * TDirectoryTreeItem is a single item in a disk directory tree view.
41 */
42public 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}