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
;
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
,
49 final DefaultTreeModel treeModel
,
50 final HierarchyTreeStructure treeStructure
,
51 final Comparator
<NodeDescriptor
> comparator
53 super(tree
, treeModel
, treeStructure
, comparator
);
56 myPsiTreeChangeListener
= new MyPsiTreeChangeListener();
57 myFileStatusListener
= new MyFileStatusListener();
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
) {
91 protected final boolean isSmartExpand() {
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
102 PsiManager
.getInstance(myProject
).removePsiTreeChangeListener(myPsiTreeChangeListener
);
103 FileStatusManager
.getInstance(myProject
).removeFileStatusListener(myFileStatusListener
);
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());