2f0b19c463061ea7a260b8b2b821b6858c6a3c1c
[idea/community.git] / platform / platform-api / src / com / intellij / ui / treeStructure / filtered / FilteringTreeStructure.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.ui.treeStructure.filtered;
17
18 import com.intellij.ide.util.treeView.AbstractTreeStructure;
19 import com.intellij.ide.util.treeView.NodeDescriptor;
20 import com.intellij.ide.util.treeView.PresentableNodeDescriptor;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.ui.speedSearch.ElementFilter;
23 import com.intellij.ui.treeStructure.CachingSimpleNode;
24 import com.intellij.ui.treeStructure.SimpleNode;
25 import org.jetbrains.annotations.NotNull;
26
27 import javax.swing.*;
28 import java.util.ArrayList;
29 import java.util.HashMap;
30 import java.util.List;
31 import java.util.Map;
32
33 public class FilteringTreeStructure extends AbstractTreeStructure {
34
35   private final ElementFilter myFilter;
36   private final AbstractTreeStructure myStructure;
37   private final Node myRoot;
38
39   private final Map<Object, Node> myNodeObject2Node = new HashMap<Object, Node>();
40
41   public FilteringTreeStructure(Project project, ElementFilter filter, AbstractTreeStructure originalStructure) {
42     myFilter = filter;
43     myStructure = originalStructure;
44     myRoot = new Node(project);
45     refilter();
46   }
47
48   public void refilter() {
49     myRoot.clear();
50     myNodeObject2Node.clear();
51     fillChildren(myRoot, getStructure().getRootElement());
52   }
53
54   private void fillChildren(Node node, Object nodeObject) {
55     node.setDelegate(nodeObject);
56     myNodeObject2Node.put(nodeObject, node);
57     Object[] nodeChildren = getStructure().getChildElements(nodeObject);
58     for (Object aNodeChildren : nodeChildren) {
59       Node nodeChild = node.add(aNodeChildren);
60       fillChildren(nodeChild, aNodeChildren);
61       if (!myFilter.shouldBeShowing(aNodeChildren) && nodeChild.getChildren().length == 0) {
62         node.remove(nodeChild);
63       }
64     }
65   }
66
67   public Node getVisibleNodeFor(Object nodeObject) {
68     return myNodeObject2Node.get(nodeObject);
69   }
70   
71   public class Node extends CachingSimpleNode {
72
73     private Object myDelegate;
74     private final List<Node> myChildren = new ArrayList<Node>();
75
76     public Node(Project project) {
77       super(project, null);
78     }
79
80     public Node(SimpleNode parent, Object delegate) {
81       super(parent);
82       myDelegate = delegate;
83     }
84
85     public void setDelegate(Object delegate) {
86       myDelegate = delegate;
87     }
88
89     public Object getDelegate() {
90       return myDelegate;
91     }
92
93     @Override
94     public String toString() {
95       return String.valueOf(getDelegate());
96     }
97
98     @Override
99     public boolean isContentHighlighted() {
100       if (myDelegate instanceof SimpleNode) {
101         return ((SimpleNode)myDelegate).isContentHighlighted();
102       }
103
104       return false;
105     }
106
107     @Override
108     public boolean isHighlightableContentNode(final PresentableNodeDescriptor kid) {
109       if (myDelegate instanceof PresentableNodeDescriptor) {
110         return ((PresentableNodeDescriptor)myDelegate).isHighlightableContentNode(kid);
111       }
112
113       return false;
114     }
115
116
117
118     @Override
119     protected void updateFileStatus() {
120       
121     }
122
123     protected void doUpdate() {
124       clearColoredText();
125       if (myDelegate instanceof PresentableNodeDescriptor) {
126         PresentableNodeDescriptor node = (PresentableNodeDescriptor)myDelegate;
127         node.update();
128         apply(node.getPresentation());
129       } else if (myDelegate != null) {
130         NodeDescriptor descriptor = getStructure().createDescriptor(myDelegate, getParentDescriptor());
131         Icon closedIcon = null;
132         Icon openIcon = null;
133         if (descriptor != null) {
134           descriptor.update();
135           closedIcon = descriptor.getClosedIcon();
136           openIcon = descriptor.getOpenIcon();
137         }
138         setIcons(closedIcon, openIcon);
139         setPlainText(myDelegate.toString());
140       }
141     }
142
143     @Override
144     public int getWeight() {
145       if (getDelegate() instanceof SimpleNode) {
146         return ((SimpleNode)getDelegate()).getWeight();
147       }
148       return super.getWeight();
149     }
150
151     public void clear() {
152       cleanUpCache();
153       myChildren.clear();
154     }
155
156     public Node add(Object child) {
157       Node childNode = new Node(this, child);
158       myChildren.add(childNode);
159       return childNode;
160     }
161
162     public void remove(Node node) {
163       myChildren.remove(node);
164     }
165
166     protected SimpleNode[] buildChildren() {
167       return myChildren.toArray(new SimpleNode[myChildren.size()]);
168     }
169
170     public Object[] getEqualityObjects() {
171       return new Object[] {myDelegate};
172     }
173   }
174
175
176   private AbstractTreeStructure getStructure() {
177     return myStructure;
178   }
179
180   public Object getRootElement() {
181     return myRoot;
182   }
183
184   public Object[] getChildElements(Object element) {
185     return ((Node) element).getChildren();
186   }
187
188   public Object getParentElement(Object element) {
189     return ((Node) element).getParent();
190   }
191
192   @NotNull
193   public NodeDescriptor createDescriptor(Object element, NodeDescriptor parentDescriptor) {
194     return (Node)element;
195   }
196
197   public void commit() {
198     getStructure().commit();
199   }
200
201
202   public boolean hasSomethingToCommit() {
203     return getStructure().hasSomethingToCommit();
204   }
205
206 }