001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: *
041: * Contributor(s): Soot Phengsy
042: */
043:
044: package org.netbeans.swing.dirchooser;
045:
046: import java.io.File;
047: import java.io.FileFilter;
048: import java.util.ArrayList;
049: import java.util.Arrays;
050: import java.util.Collections;
051: import java.util.Comparator;
052: import javax.swing.JFileChooser;
053: import javax.swing.tree.DefaultMutableTreeNode;
054: import org.netbeans.api.project.ProjectManager;
055: import org.openide.filesystems.FileObject;
056: import org.openide.filesystems.FileUtil;
057: import org.openide.util.Utilities;
058:
059: /**
060: * A directory tree node.
061: *
062: * @author Soot Phengsy
063: */
064: public class DirectoryNode extends DefaultMutableTreeNode {
065:
066: public final static int SINGLE_SELECTION = 0;
067:
068: public final static int DIG_IN_SELECTION = 4;
069:
070: /** case insensitive file name's comparator */
071: static final FileNameComparator FILE_NAME_COMPARATOR = new FileNameComparator();
072:
073: private File directory;
074:
075: private boolean isDir;
076:
077: private boolean loaded;
078:
079: private boolean interim;
080:
081: private boolean isSelected;
082:
083: private boolean isEditable;
084:
085: private boolean expanded;
086:
087: public DirectoryNode(File file) {
088: this (file, true, false, false, false);
089: }
090:
091: public DirectoryNode(File file, boolean allowsChildren) {
092: this (file, allowsChildren, false, false, false);
093: }
094:
095: public DirectoryNode(File file, boolean allowsChildren,
096: boolean isSelected, boolean isChecked, boolean isEditable) {
097: super (file, allowsChildren);
098: this .directory = file;
099: this .isDir = directory.isDirectory();
100: this .isSelected = isSelected;
101: }
102:
103: public boolean isLoaded() {
104: return this .loaded;
105: }
106:
107: public File getFile() {
108: return this .directory;
109: }
110:
111: public void setFile(File file) {
112: setUserObject(file);
113: this .directory = file;
114: this .loaded = false;
115: }
116:
117: public void setSelected(boolean isSelected) {
118: this .isSelected = isSelected;
119: }
120:
121: public boolean isLeaf() {
122: return !this .isDir;
123: }
124:
125: public boolean getAllowsChildren() {
126: return this .isDir;
127: }
128:
129: public boolean isSelected() {
130: return this .isSelected;
131: }
132:
133: public boolean loadChildren(JFileChooser chooser, boolean descend) {
134: //fixed bug #97124
135: if (loaded == false) {
136:
137: ArrayList files = getFiles(chooser);
138:
139: if (files.size() == 0) {
140: return false;
141: }
142:
143: for (int i = 0; i < files.size(); i++) {
144: File child = (File) files.get(i);
145:
146: if (chooser.accept(child)) {
147: try {
148: DirectoryNode node = new DirectoryNode(child);
149: if (descend == false) {
150: break;
151: }
152: add(node);
153: } catch (NullPointerException t) {
154: t.printStackTrace();
155: }
156: }
157: }
158:
159: if (descend == true || (getChildCount() > 0)) {
160: loaded = true;
161: }
162: }
163:
164: return loaded;
165: }
166:
167: private ArrayList getFiles(JFileChooser chooser) {
168: //fixed bug #97124
169: ArrayList list = new ArrayList();
170:
171: File[] files = chooser.getFileSystemView().getFiles(directory,
172: chooser.isFileHidingEnabled());
173: int mode = chooser.getFileSelectionMode();
174: if (mode == JFileChooser.DIRECTORIES_ONLY) {
175: for (int i = 0; i < files.length; i++) {
176: File child = files[i];
177: if (child.isDirectory()) {
178: list.add(child);
179: }
180: }
181: Collections.sort(list, FILE_NAME_COMPARATOR);
182: } else if (mode == JFileChooser.FILES_AND_DIRECTORIES
183: || mode == JFileChooser.FILES_ONLY) {
184: ArrayList dirList = new ArrayList();
185: ArrayList fileList = new ArrayList();
186: for (int i = 0; i < files.length; i++) {
187: File child = files[i];
188: if (child.isDirectory()) {
189: dirList.add(child);
190: } else {
191: fileList.add(child);
192: }
193: }
194:
195: Collections.sort(dirList, FILE_NAME_COMPARATOR);
196: Collections.sort(fileList, FILE_NAME_COMPARATOR);
197:
198: list.addAll(dirList);
199: list.addAll(fileList);
200: }
201:
202: return list;
203: }
204:
205: public boolean isNetBeansProject() {
206: return isNetBeansProject(directory);
207: }
208:
209: public static boolean isNetBeansProject(File directory) {
210: boolean retVal = false;
211: if (directory != null) {
212: FileObject fo = convertToValidDir(directory);
213: if (fo != null) {
214: if (Utilities.isUnix() && fo.getParent() != null
215: && fo.getParent().getParent() == null) {
216: retVal = false; // Ignore all subfolders of / on unixes
217: // (e.g. /net, /proc)
218: } else {
219: retVal = ProjectManager.getDefault().isProject(fo);
220: }
221: }
222: }
223: return retVal;
224: }
225:
226: private static FileObject convertToValidDir(File f) {
227: FileObject fo;
228: File testFile = new File(f.getPath());
229: if (testFile == null || testFile.getParent() == null) {
230: // BTW this means that roots of file systems can't be project
231: // directories.
232: return null;
233: }
234:
235: /**
236: *
237: * ATTENTION: on Windows may occure dir.isDirectory () == dir.isFile () ==
238: *
239: * true then its used testFile instead of dir.
240: *
241: */
242: if (!testFile.isDirectory()) {
243: return null;
244: }
245:
246: fo = FileUtil.toFileObject(FileUtil.normalizeFile(testFile));
247: return fo;
248: }
249:
250: private class DirectoryFilter implements FileFilter {
251: public boolean accept(File f) {
252: return f.isDirectory();
253: }
254:
255: public String getDescription() {
256: return "Directory";
257: }
258: }
259:
260: /** Compares files ignoring case sensitivity */
261: private static class FileNameComparator implements Comparator<File> {
262:
263: public int compare(File f1, File f2) {
264: return String.CASE_INSENSITIVE_ORDER.compare(f1.getName(),
265: f2.getName());
266: }
267:
268: }
269:
270: }
|