Olesya Smirnova
2005-02-25 20:35:55 +03:00
parent 00ed32bc16
commit 60eeccec0e
4 changed files with 198 additions and 60 deletions
@@ -0,0 +1,178 @@
package com.intellij.ide.util.treeView;
import com.intellij.openapi.util.*;
import com.intellij.util.ui.tree.TreeUtil;
import org.jdom.Element;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class TreeState implements JDOMExternalizable{
private static final String PATH = "PATH";
private static final String PATH_ELEMENT = "PATH_ELEMENT";
static class PathElement implements JDOMExternalizable{
public String myItemId;
public String myItemType;
public PathElement(final String itemId, final String itemType) {
myItemId = itemId;
myItemType = itemType;
}
public PathElement() {
}
public boolean matchedWith(NodeDescriptor nodeDescriptor) {
return Comparing.equal(myItemId, nodeDescriptor.toString()) &&
Comparing.equal(myItemType, nodeDescriptor.getClass().getName());
}
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
public void writeExternal(Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element);
}
}
private final List<List<PathElement>> myPaths;
private TreeState(List<List<PathElement>> paths) {
myPaths = paths;
}
public TreeState() {
myPaths = new ArrayList<List<PathElement>>();
}
public void readExternal(Element element) throws InvalidDataException {
myPaths.clear();
final List paths = element.getChildren(PATH);
for (Iterator iterator = paths.iterator(); iterator.hasNext();) {
Element xmlPathElement = (Element)iterator.next();
myPaths.add(readPath(xmlPathElement));
}
}
private List<PathElement> readPath(final Element xmlPathElement) throws InvalidDataException {
final ArrayList<PathElement> result = new ArrayList<PathElement>();
final List elements = xmlPathElement.getChildren(PATH_ELEMENT);
for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
Element xmlPathElementElement = (Element)iterator.next();
final PathElement pathElement = new PathElement();
pathElement.readExternal(xmlPathElementElement);
result.add(pathElement);
}
return result;
}
public void writeExternal(Element element) throws WriteExternalException {
for (Iterator<List<PathElement>> iterator = myPaths.iterator(); iterator.hasNext();) {
List<PathElement> path = iterator.next();
final Element pathElement = new Element(PATH);
writeExternal(pathElement, path);
element.addContent(pathElement);
}
}
private void writeExternal(final Element pathXmlElement, final List<PathElement> path) throws WriteExternalException {
for (Iterator<PathElement> iterator = path.iterator(); iterator.hasNext();) {
final Element pathXmlElementElement = new Element(PATH_ELEMENT);
PathElement pathElement = iterator.next();
pathElement.writeExternal(pathXmlElementElement);
pathXmlElement.addContent(pathXmlElementElement);
}
}
public static TreeState createOn(JTree tree) {
return new TreeState(createPaths(tree));
}
private static List<List<PathElement>> createPaths(final JTree tree) {
final ArrayList<List<PathElement>> result = new ArrayList<List<PathElement>>();
final ArrayList<TreePath> expandedPaths = TreeUtil.collectExpandedPaths(tree);
for (Iterator<TreePath> iterator = expandedPaths.iterator(); iterator.hasNext();) {
final List<PathElement> path = createPath(iterator.next());
if (path != null) {
result.add(path);
}
}
return result;
}
private static List<PathElement> createPath(final TreePath treePath) {
final ArrayList<PathElement> result = new ArrayList<PathElement>();
for (int i = 0; i < treePath.getPathCount(); i++) {
final Object pathComponent = treePath.getPathComponent(i);
if (pathComponent instanceof DefaultMutableTreeNode) {
final Object userObject = ((DefaultMutableTreeNode)pathComponent).getUserObject();
if (userObject instanceof NodeDescriptor) {
final NodeDescriptor nodeDescriptor = ((NodeDescriptor)userObject);
nodeDescriptor.update();
final String key = nodeDescriptor.toString();
final String type = nodeDescriptor.getClass().getName();
result.add(new PathElement(key, type));
} else {
return null;
}
} else {
return null;
}
}
return result;
}
public void applyTo(JTree tree) {
for (Iterator<List<PathElement>> iterator = myPaths.iterator(); iterator.hasNext();) {
applyTo(iterator.next(), tree);
}
}
private void applyTo(final List<PathElement> path, final JTree tree) {
applyTo(0, path, tree.getModel().getRoot(), tree);
}
private boolean applyTo(final int positionInPath, final List<PathElement> path, final Object root, JTree tree) {
if (!(root instanceof DefaultMutableTreeNode)) return false;
final DefaultMutableTreeNode treeNode = ((DefaultMutableTreeNode)root);
final Object userObject = treeNode.getUserObject();
if (!(userObject instanceof NodeDescriptor)) return false;
final NodeDescriptor nodeDescriptor = ((NodeDescriptor)userObject);
final PathElement pathElement = path.get(positionInPath);
if (!pathElement.matchedWith(nodeDescriptor)) return false;
final TreePath currentPath = new TreePath(treeNode.getPath());
if (!tree.isExpanded(currentPath)) {
tree.expandPath(currentPath);
}
if (positionInPath == path.size() - 1) {
return true;
}
for (int j = 0; j < treeNode.getChildCount(); j++) {
final TreeNode child = treeNode.getChildAt(j);
final boolean resultFromChild = applyTo(positionInPath + 1, path, child, tree);
if (resultFromChild) {
break;
}
}
return true;
}
}
@@ -19,7 +19,6 @@ import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.pom.Navigatable;
import com.intellij.ui.AutoScrollToSourceHandler;
@@ -29,7 +28,6 @@ import com.intellij.ui.TreeToolTipHandler;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.ui.Tree;
import com.intellij.util.ui.tree.TreeUtil;
import org.jdom.Element;
import javax.swing.*;
import javax.swing.event.TreeModelEvent;
@@ -50,9 +48,6 @@ public abstract class AbstractProjectViewPSIPane extends AbstractProjectViewPane
protected AbstractProjectViewPSIPane(Project project) {
super(project);
myExpandedElements.registerExpandedElementProvider(new ClassUrl(null, null));
myExpandedElements.registerExpandedElementProvider(new ModuleUrl(null, null));
myExpandedElements.registerExpandedElementProvider(new DirectoryUrl(null, null));
}
protected final void initPSITree() {
@@ -123,8 +118,6 @@ public abstract class AbstractProjectViewPSIPane extends AbstractProjectViewPane
}
}
});
myExpandedElements.restoreExpandedElements(this, myProject);
}
public final void expand(Object[] path) {
@@ -195,6 +188,7 @@ public abstract class AbstractProjectViewPSIPane extends AbstractProjectViewPane
selectInManager.addTarget(createSelectInTarget());
initPSITree();
restoreState();
}
protected abstract ProjectViewSelectInTarget createSelectInTarget();
@@ -273,14 +267,4 @@ public abstract class AbstractProjectViewPSIPane extends AbstractProjectViewPane
public JComponent getComponent() {
return myComponent;
}
public void readExternal(Element viewElement) throws InvalidDataException {
myExpandedElements.readExternal(viewElement);
}
public void writeExternal(Element viewElement) {
new ExpandedElements(getExpandedUrls()).writeExternal(viewElement);
}
}
@@ -8,11 +8,14 @@ import com.intellij.ide.projectView.impl.nodes.PackageElement;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.ide.util.treeView.TreeState;
import com.intellij.openapi.actionSystem.DataConstants;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
@@ -24,7 +27,8 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import java.util.ArrayList;
import java.util.List;
import java.util.Enumeration;
import org.jdom.Element;
public abstract class AbstractProjectViewPane implements JDOMExternalizable, DataProvider {
@@ -33,7 +37,7 @@ public abstract class AbstractProjectViewPane implements JDOMExternalizable, Dat
protected ProjectViewTree myTree;
protected AbstractTreeStructure myTreeStructure;
protected BaseProjectTreeBuilder myTreeBuilder;
protected final ExpandedElements myExpandedElements = new ExpandedElements();
private final TreeState myReadTreeState = new TreeState();
protected final void fireTreeChangeListener() {
if (myTreeChangeListener != null) myTreeChangeListener.run();
@@ -70,48 +74,9 @@ public abstract class AbstractProjectViewPane implements JDOMExternalizable, Dat
autoScrollFromSourceHandler.install();
}
protected final List<AbstractUrl> getExpandedUrls(){
if (myTree == null) {
// this is the case when invoked on partially initialized/disposed ProjectView
return new ArrayList<AbstractUrl>();
}
List<AbstractUrl> urls = new ArrayList<AbstractUrl>();
DefaultMutableTreeNode rootNode = (DefaultMutableTreeNode)myTree.getModel().getRoot();
Enumeration descendants = myTree.getExpandedDescendants(new TreePath(rootNode.getPath()));
if (descendants != null) {
NextDescendant:
while (descendants.hasMoreElements()) {
TreePath treePath = (TreePath)descendants.nextElement();
// build up path from tree node elements
Object[] path = treePath.getPath();
List<Object> elementsPath = new ArrayList<Object>(path.length);
for (int i = 0; i < path.length; i++) {
Object node = path[i];
if (node instanceof DefaultMutableTreeNode) {
DefaultMutableTreeNode mutableNode = (DefaultMutableTreeNode)node;
if (mutableNode.getUserObject() instanceof AbstractTreeNode) {
AbstractTreeNode descriptor = (AbstractTreeNode)mutableNode.getUserObject();
Object element = descriptor.getValue();
if (element != null) {
elementsPath.add(element);
} else {
continue NextDescendant;
}
}
}
}
AbstractUrl url = myExpandedElements.createUrlByPath(elementsPath);
if (url != null) {
urls.add(url);
}
}
}
return urls;
}
public void addToolbarActions(DefaultActionGroup actionGroup) {
}
public Object getData(String dataId) {
if (DataConstants.NAVIGATABLE.equals(dataId)){
TreePath[] paths = getSelectionPaths();
@@ -211,4 +176,16 @@ public abstract class AbstractProjectViewPane implements JDOMExternalizable, Dat
public BaseProjectTreeBuilder getTreeBuilder() {
return myTreeBuilder;
}
public void readExternal(Element element) throws InvalidDataException {
myReadTreeState.readExternal(element);
}
public void writeExternal(Element element) throws WriteExternalException {
TreeState.createOn(myTree).writeExternal(element);
}
public final void restoreState(){
myReadTreeState.applyTo(myTree);
}
}
@@ -38,7 +38,6 @@ public final class PackageViewPane extends AbstractProjectViewPSIPane implements
public PackageViewPane(Project project) {
super(project);
myExpandedElements.registerExpandedElementProvider(new PackageUrl(null,null));
}
public String getTitle() {