StructureView updating fixed

This commit is contained in:
Olesya Smirnova
2005-02-08 15:33:25 +03:00
parent d289f016c9
commit 26978ff1dc
6 changed files with 79 additions and 33 deletions
@@ -35,6 +35,7 @@ import com.intellij.ide.structureView.StructureViewExtension;
import com.intellij.ide.structureView.StructureViewFactory;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Iconable;
import com.intellij.psi.PsiElement;
@@ -91,4 +92,20 @@ public abstract class PsiTreeElementBase implements StructureViewTreeElement, It
}
public abstract StructureViewTreeElement[] getChildrenBase();
public int hashCode() {
if (getElement() == null) {
return 0;
} else {
return getElement().hashCode();
}
}
public boolean equals(Object object) {
if (object instanceof PsiTreeElementBase) {
return Comparing.equal(getElement(), ((PsiTreeElementBase)object).getElement());
} else {
return false;
}
}
}
@@ -5,6 +5,7 @@ import com.intellij.ide.util.treeView.smartTree.SmartTreeStructure;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiModificationTracker;
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
@@ -15,21 +16,17 @@ final class StructureTreeBuilder extends AbstractTreeBuilder {
private final MyCopyPasteListener myCopyPasteListener;
private final PsiTreeChangeListener myPsiTreeChangeListener;
private final StructureViewComponent myStructureViewComponent;
private boolean myStateIsSaved = false;
public StructureTreeBuilder(Project project,
JTree tree,
DefaultTreeModel treeModel,
AbstractTreeStructure treeStructure,
final StructureViewComponent structureViewComponent) {
JTree tree,
DefaultTreeModel treeModel,
AbstractTreeStructure treeStructure) {
super(
tree,
treeModel,
treeStructure, null
);
myStructureViewComponent = structureViewComponent;
myProject = project;
myPsiTreeChangeListener = new MyPsiTreeChangeListener();
@@ -38,19 +35,6 @@ final class StructureTreeBuilder extends AbstractTreeBuilder {
myCopyPasteListener = new MyCopyPasteListener();
CopyPasteManager.getInstance().addContentChangedListener(myCopyPasteListener);
initRootNode();
myUpdater.runAfterUpdate(new Runnable() {
public void run() {
if (myStateIsSaved) {
try {
myStructureViewComponent.restoreStructureViewState();
}
finally {
myStateIsSaved = false;
}
}
}
});
}
public void dispose() {
@@ -82,9 +66,18 @@ final class StructureTreeBuilder extends AbstractTreeBuilder {
private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
private final PsiModificationTracker myModificationTracker;
private long myOutOfCodeBlockModificationCount;
public MyPsiTreeChangeListener() {
myModificationTracker = PsiManager.getInstance(myProject).getModificationTracker();
myOutOfCodeBlockModificationCount = myModificationTracker.getOutOfCodeBlockModificationCount();
}
public void childRemoved(PsiTreeChangeEvent event) {
PsiElement child = event.getOldChild();
if (child instanceof PsiWhiteSpace) return; //optimization
childrenChanged();
}
@@ -112,16 +105,16 @@ final class StructureTreeBuilder extends AbstractTreeBuilder {
}
private void childrenChanged() {
if (!myStateIsSaved) {
try {
myStructureViewComponent.saveStructureViewState();
}
finally {
myStateIsSaved = true;
}
if (myOutOfCodeBlockModificationCount == myModificationTracker.getOutOfCodeBlockModificationCount()) {
return;
}
try {
((SmartTreeStructure)getTreeStructure()).rebuildTree();
myUpdater.addSubtreeToUpdate(myRootNode);
}
finally {
myOutOfCodeBlockModificationCount = myModificationTracker.getOutOfCodeBlockModificationCount();
}
((SmartTreeStructure)getTreeStructure()).rebuildTree();
myUpdater.addSubtreeToUpdate(myRootNode);
return;
}
@@ -76,8 +76,7 @@ public class StructureViewComponent extends JPanel implements TreeActionsOwner,
SmartTreeStructure treeStructure = new SmartTreeStructure(project, myTreeModelWrapper);
JTree tree = new JTree(new DefaultTreeModel(new DefaultMutableTreeNode(treeStructure.getRootElement())));
myAbstractTreeBuilder = new StructureTreeBuilder(project, tree,
(DefaultTreeModel)tree.getModel(),treeStructure,
this);
(DefaultTreeModel)tree.getModel(),treeStructure);
myAbstractTreeBuilder.updateFromRoot();
add(new JScrollPane(myAbstractTreeBuilder.getTree()), BorderLayout.CENTER);
@@ -304,6 +303,7 @@ public class StructureViewComponent extends JPanel implements TreeActionsOwner,
JTree tree = myAbstractTreeBuilder.getTree();
DefaultMutableTreeNode currentTreeNode = ((DefaultMutableTreeNode)tree.getModel().getRoot());
pathToElement.remove(0);
DefaultMutableTreeNode result = null;
while (currentTreeNode != null) {
AbstractTreeNode topPathElement = null;
if (!pathToElement.isEmpty()) {
@@ -316,11 +316,12 @@ public class StructureViewComponent extends JPanel implements TreeActionsOwner,
if (!tree.isExpanded(treePath)) tree.expandPath(treePath);
if (topPathElement != null) {
currentTreeNode = findInChildren(currentTreeNode, topPathElement);
result = currentTreeNode;
} else {
currentTreeNode = null;
}
}
return currentTreeNode;
return result;
}
public boolean select(Object element, boolean requestFocus) {
@@ -7,6 +7,7 @@ import java.util.*;
public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<Value> {
private List<CachingChildrenTreeNode> myChildren;
private List<CachingChildrenTreeNode> myOldChildren = null;
protected final TreeModel myTreeModel;
public CachingChildrenTreeNode(Project project, Value value, TreeModel treeModel) {
@@ -164,8 +165,27 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
private void rebuildSubtree() {
initChildren();
performTreeActions();
synchronizeChildren();
}
protected void synchronizeChildren() {
if (myOldChildren != null) {
for (Iterator<CachingChildrenTreeNode> iterator = myOldChildren.iterator(); iterator.hasNext();) {
CachingChildrenTreeNode oldInstance = iterator.next();
if (myChildren.contains(oldInstance)) {
final int newIndex = myChildren.indexOf(oldInstance);
final CachingChildrenTreeNode newInstance = myChildren.get(newIndex);
oldInstance.copyFromNew(newInstance);
myChildren.set(newIndex, oldInstance);
}
}
}
}
protected abstract void copyFromNew(final CachingChildrenTreeNode newInstance);
protected abstract void performTreeActions();
protected abstract void initChildren();
@@ -175,7 +195,13 @@ public abstract class CachingChildrenTreeNode <Value> extends AbstractTreeNode<V
}
public void rebuildChildren() {
myChildren = null;
if (myChildren != null) {
myOldChildren = myChildren;
for (Iterator<CachingChildrenTreeNode> iterator = myChildren.iterator(); iterator.hasNext();) {
iterator.next().rebuildChildren();
}
myChildren = null;
}
}
@@ -9,6 +9,11 @@ class GroupWrapper extends CachingChildrenTreeNode<Group> {
super(project, value, treeModel);
}
public void copyFromNew(final CachingChildrenTreeNode newInstance) {
setChildren(newInstance.getChildren());
synchronizeChildren();
}
public boolean contains(VirtualFile file) {
return false;
}
@@ -9,6 +9,10 @@ class TreeElementWrapper extends CachingChildrenTreeNode<TreeElement>{
super(project, value, treeModel);
}
public void copyFromNew(final CachingChildrenTreeNode newInstance) {
}
public void initChildren() {
clearChildren();
TreeElement[] children = getValue().getChildren();