ComponentWithBrowseButton - optional remove listener on hide
[fedora-idea.git] / platform / lang-impl / src / com / intellij / ide / hierarchy / HierarchyTreeBuilder.java
blobf54e41dbae83c719fb1709882fc76699d27a5e9a
1 /*
2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.intellij.ide.hierarchy;
19 import com.intellij.ide.util.treeView.AbstractTreeBuilder;
20 import com.intellij.ide.util.treeView.NodeDescriptor;
21 import com.intellij.ide.util.treeView.TreeBuilderUtil;
22 import com.intellij.openapi.progress.ProgressIndicator;
23 import com.intellij.openapi.progress.util.StatusBarProgress;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.util.Disposer;
26 import com.intellij.openapi.util.Pair;
27 import com.intellij.openapi.vcs.FileStatusListener;
28 import com.intellij.openapi.vcs.FileStatusManager;
29 import com.intellij.openapi.vfs.VirtualFile;
30 import com.intellij.psi.PsiManager;
31 import com.intellij.psi.PsiTreeChangeAdapter;
32 import com.intellij.psi.PsiTreeChangeEvent;
33 import com.intellij.psi.PsiTreeChangeListener;
34 import org.jetbrains.annotations.NotNull;
36 import javax.swing.*;
37 import javax.swing.tree.DefaultTreeModel;
38 import java.util.ArrayList;
39 import java.util.Comparator;
41 public class HierarchyTreeBuilder extends AbstractTreeBuilder {
42 private final Project myProject;
44 private final PsiTreeChangeListener myPsiTreeChangeListener;
45 private final MyFileStatusListener myFileStatusListener;
47 public HierarchyTreeBuilder(final Project project,
48 final JTree tree,
49 final DefaultTreeModel treeModel,
50 final HierarchyTreeStructure treeStructure,
51 final Comparator<NodeDescriptor> comparator
52 ) {
53 super(tree, treeModel, treeStructure, comparator);
54 myProject = project;
56 myPsiTreeChangeListener = new MyPsiTreeChangeListener();
57 myFileStatusListener = new MyFileStatusListener();
59 initRootNode();
60 PsiManager.getInstance(myProject).addPsiTreeChangeListener(myPsiTreeChangeListener);
61 FileStatusManager.getInstance(myProject).addFileStatusListener(myFileStatusListener);
63 Disposer.register(myProject, this);
66 public final Object storeExpandedAndSelectedInfo() {
67 final ArrayList<Object> pathsToExpand = new ArrayList<Object>();
68 final ArrayList<Object> selectionPaths = new ArrayList<Object>();
69 TreeBuilderUtil.storePaths(this, getRootNode(), pathsToExpand, selectionPaths, true);
70 return new Pair<ArrayList<Object>, ArrayList<Object>>(pathsToExpand, selectionPaths);
73 public final void restoreExpandedAndSelectedInfo(final Object info) {
74 final Pair pair = (Pair)info;
75 TreeBuilderUtil.restorePaths(this, (ArrayList)pair.first, (ArrayList)pair.second, true);
78 protected boolean isAlwaysShowPlus(final NodeDescriptor nodeDescriptor) {
79 return ((HierarchyTreeStructure) getTreeStructure()).isAlwaysShowPlus();
82 protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
83 if (getTreeStructure().getRootElement().equals(nodeDescriptor.getElement())) return true;
85 if (nodeDescriptor instanceof HierarchyNodeDescriptor) {
86 return false;
88 return true;
91 protected final boolean isSmartExpand() {
92 return false;
95 protected final boolean isDisposeOnCollapsing(final NodeDescriptor nodeDescriptor) {
96 return false; // prevents problems with building descriptors for invalidated elements
99 public final void dispose() {
100 if (!isDisposed()) { // because can be called both externally and via my ProjectManagerListener, don't know what will happen earlier
101 super.dispose();
102 PsiManager.getInstance(myProject).removePsiTreeChangeListener(myPsiTreeChangeListener);
103 FileStatusManager.getInstance(myProject).removeFileStatusListener(myFileStatusListener);
107 @NotNull
108 protected ProgressIndicator createProgressIndicator() {
109 return new StatusBarProgress();
112 private final class MyPsiTreeChangeListener extends PsiTreeChangeAdapter {
113 public final void childAdded(final PsiTreeChangeEvent event) {
114 getUpdater().addSubtreeToUpdate(getRootNode());
117 public final void childRemoved(final PsiTreeChangeEvent event) {
118 getUpdater().addSubtreeToUpdate(getRootNode());
121 public final void childReplaced(final PsiTreeChangeEvent event) {
122 getUpdater().addSubtreeToUpdate(getRootNode());
125 public final void childMoved(final PsiTreeChangeEvent event) {
126 getUpdater().addSubtreeToUpdate(getRootNode());
129 public final void childrenChanged(final PsiTreeChangeEvent event) {
130 getUpdater().addSubtreeToUpdate(getRootNode());
133 public final void propertyChanged(final PsiTreeChangeEvent event) {
134 getUpdater().addSubtreeToUpdate(getRootNode());
138 private final class MyFileStatusListener implements FileStatusListener {
139 public final void fileStatusesChanged() {
140 getUpdater().addSubtreeToUpdate(getRootNode());
143 public final void fileStatusChanged(@NotNull final VirtualFile virtualFile) {
144 getUpdater().addSubtreeToUpdate(getRootNode());