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