mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
This commit is contained in:
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user