From 26978ff1dc3869ce9ef9190e51ce94c587ff4432 Mon Sep 17 00:00:00 2001 From: Olesya Smirnova Date: Tue, 8 Feb 2005 15:33:25 +0300 Subject: [PATCH] StructureView updating fixed --- .../impl/common/PsiTreeElementBase.java | 17 +++++++ .../StructureTreeBuilder.java | 51 ++++++++----------- .../StructureViewComponent.java | 7 +-- .../smartTree/CachingChildrenTreeNode.java | 28 +++++++++- .../util/treeView/smartTree/GroupWrapper.java | 5 ++ .../smartTree/TreeElementWrapper.java | 4 ++ 6 files changed, 79 insertions(+), 33 deletions(-) diff --git a/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java b/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java index d05bc0050167..75728cc672e9 100644 --- a/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java +++ b/source/com/intellij/ide/structureView/impl/common/PsiTreeElementBase.java @@ -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; + } + } } diff --git a/source/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java b/source/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java index 41fdaee8a064..304662ddd69f 100644 --- a/source/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java +++ b/source/com/intellij/ide/structureView/newStructureView/StructureTreeBuilder.java @@ -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; } diff --git a/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java b/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java index 7cde1139615b..14ae1c58833c 100644 --- a/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java +++ b/source/com/intellij/ide/structureView/newStructureView/StructureViewComponent.java @@ -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) { diff --git a/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java b/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java index 5a2cf526fcbe..bdf47395c0bb 100644 --- a/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java +++ b/source/com/intellij/ide/util/treeView/smartTree/CachingChildrenTreeNode.java @@ -7,6 +7,7 @@ import java.util.*; public abstract class CachingChildrenTreeNode extends AbstractTreeNode { private List myChildren; + private List myOldChildren = null; protected final TreeModel myTreeModel; public CachingChildrenTreeNode(Project project, Value value, TreeModel treeModel) { @@ -164,8 +165,27 @@ public abstract class CachingChildrenTreeNode extends AbstractTreeNode 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 extends AbstractTreeNode iterator = myChildren.iterator(); iterator.hasNext();) { + iterator.next().rebuildChildren(); + } + myChildren = null; + } } diff --git a/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java b/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java index e460d7a13b9b..b334417fa098 100644 --- a/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java +++ b/source/com/intellij/ide/util/treeView/smartTree/GroupWrapper.java @@ -9,6 +9,11 @@ class GroupWrapper extends CachingChildrenTreeNode { super(project, value, treeModel); } + public void copyFromNew(final CachingChildrenTreeNode newInstance) { + setChildren(newInstance.getChildren()); + synchronizeChildren(); + } + public boolean contains(VirtualFile file) { return false; } diff --git a/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java b/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java index 97b672e228ad..3a3f6a445c11 100644 --- a/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java +++ b/source/com/intellij/ide/util/treeView/smartTree/TreeElementWrapper.java @@ -9,6 +9,10 @@ class TreeElementWrapper extends CachingChildrenTreeNode{ super(project, value, treeModel); } + public void copyFromNew(final CachingChildrenTreeNode newInstance) { + + } + public void initChildren() { clearChildren(); TreeElement[] children = getValue().getChildren();