/* * @(#)DirTreeNode.java * * This file is part of webCDwriter - Network CD Writing. * * Copyright (C) 1999-2004 Jörg P. M. Haeger * * webCDwriter is free software. See CDcreator.java for details. */ import java.io.*; import javax.swing.tree.*; /** * DirTreeNode * * @version 20040317 * @author Jörg P. M. Haeger */ class DirTreeNode implements MutableTreeNode { private TreeNode parent; private String name; protected File file; protected boolean expanded, isDir, isExe; protected TreeNodesList childs; DirTreeNode(String aName) { parent = null; name = aName; file = null; childs = new TreeNodesList(10); expanded = true; isDir = true; isExe = false; } DirTreeNode(File aFile) { this(aFile, false); } DirTreeNode(File aFile, boolean root) { parent = null; name = aFile.getName(); if (name.length() == 0) if (aFile.getPath().length() > 0) name = aFile.getPath().substring(0, 1) + ":"; else name = "a"; file = aFile; expanded = false; isDir = root; if (!isDir) isDir = file.isDirectory(); isExe = false; } public java.util.Enumeration children() { return null; } public static int compare(TreeNode a, TreeNode b) { String aStr = a.toString().toLowerCase(); String bStr = b.toString().toLowerCase(); if (a.isLeaf()) if (b.isLeaf()) return aStr.compareTo(bStr); else return 1; else if (b.isLeaf()) return -1; else return aStr.compareTo(bStr); } protected DirTreeNode createNode(File file) { return new DirTreeNode(file); } private DirTreeNode createNode2(File file) { DirTreeNode node = createNode(file); node.setParent(this); return node; } public boolean getAllowsChildren() { return !isLeaf(); } public TreeNode getChildAt(int childIndex) { expand(); return childs.getNode(childIndex); } public int getChildCount() { expand(); return childs.getNumOfNodes(); } public File getFile() { return file; } public int getIndex(String name) { for (int i = 0; i < getChildCount(); i++) if (getChildAt(i).toString().equals(name)) return i; return -1; } public int getIndex(TreeNode node) { for (int i = 0; i < getChildCount(); i++) if (getChildAt(i) == node) return i; return -1; } public TreeNode getParent() { return parent; } protected void expand() { if (expanded) return; if (file == null) { expanded = true; return; } // System.out.println("expand(): " + name); File files[] = ((File2)file).listFiles(); int filesNum; if (files == null) filesNum = 0; else filesNum = files.length; childs = new TreeNodesList(filesNum + 10); expanded = true; for (int i = 0; i < filesNum; i++) { File f = files[i]; if (!Mode.audioCD() || f.isDirectory() || f.getName().toLowerCase() .endsWith(".wav") || (CDcreator.mp3Support && f.getName().toLowerCase() .endsWith(".mp3")) || (CDcreator.oggSupport && f.getName().toLowerCase() .endsWith(".ogg"))) // insert2(createNode(f)); childs.append(createNode2(f)); } childs.sort(); } public void insert(MutableTreeNode child) { insert2(child); file = null; } public void insert(MutableTreeNode child, int index) { insert2(child, index); file = null; } private void insert2(MutableTreeNode child) { expand(); int i; for (i = 0; i < childs.getNumOfNodes() && compare(childs.getNode(i), child) < 0; i++); if (Mode.type == Mode.audio) i = childs.getNumOfNodes(); insert2(child, i); } private void insert2(MutableTreeNode child, int index) { expand(); childs.insert(child, index); child.setParent(this); } public boolean isExecutable() { return isExe; } public boolean isExpanded() { return expanded; } public boolean isLeaf() { return !isDir; } public void remove(int index) { if (index < 0) { System.out.println("DirTreeNode.remove: index = " + index); return; } ((MutableTreeNode)childs.getNode(index)).setParent(null); childs.remove(index); file = null; } public void remove(MutableTreeNode node) { remove(getIndex(node)); } public void removeFromParent() { ((MutableTreeNode)getParent()).remove(this); } public void resetExpanded() { expanded = false; } public void setParent(MutableTreeNode newParent) { parent = newParent; } public void setUserObject(Object object) { name = (String)object; } public String toString() { return name; } protected static class TreeNodesList { public TreeNodesList(int initialSize) { nodes = new TreeNode[initialSize]; numOfNodes = 0; } public void append(TreeNode node) { insert(node, numOfNodes); } private int compare(int a, int b) { return DirTreeNode.compare(nodes[a], nodes[b]); } public TreeNode getNode(int index) { return nodes[index]; } public int getNumOfNodes() { return numOfNodes; } public void insert(TreeNode node, int index) { if (index > numOfNodes) return; if (numOfNodes == nodes.length) { TreeNode[] old = nodes; nodes = new TreeNode[numOfNodes + 100]; for (int i = 0; i < numOfNodes; i++) nodes[i] = old[i]; } for (int i = numOfNodes; i > index; i--) nodes[i] = nodes[i-1]; nodes[index] = node; numOfNodes++; } public void remove(int index) { if (index < 0) return; for (int i = index; i < numOfNodes - 1; i++) nodes[i] = nodes[i+1]; numOfNodes--; } public void sort() { // create a heap for (int i = 1; i < numOfNodes; i++) { int child, parent = i; while (true) { child = parent; parent = (parent + 1) / 2 - 1; if (compare(parent, child) >= 0) break; swap(parent, child); if (parent == 0) break; } } // remove the root and repair the heap for (int i = numOfNodes - 1; i > 0; i--) { swap(0, i); int parent = 0; while (true) { int child = 2 * (parent + 1) - 1; if (child >= i) break; if (child + 1 < i && compare(child, child + 1) < 0) child++; if (compare(parent, child) < 0) { swap(parent, child); parent = child; } else break; } } } private void swap(int a, int b) { TreeNode node = nodes[a]; nodes[a] = nodes[b]; nodes[b] = node; } protected TreeNode nodes[]; protected int numOfNodes; } }