IDEA-50121
[fedora-idea.git] / java / java-impl / src / com / intellij / slicer / SliceNode.java
blob827b1444dae29c2a9111d5cf70b224ec0351cecf
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.
16 package com.intellij.slicer;
18 import com.intellij.ide.projectView.PresentationData;
19 import com.intellij.ide.util.treeView.AbstractTreeNode;
20 import com.intellij.openapi.progress.ProgressIndicator;
21 import com.intellij.openapi.progress.ProgressManager;
22 import com.intellij.openapi.progress.impl.ProgressManagerImpl;
23 import com.intellij.openapi.progress.util.ProgressIndicatorBase;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.ui.DuplicateNodeRenderer;
26 import com.intellij.usageView.UsageViewBundle;
27 import com.intellij.util.ArrayUtil;
28 import com.intellij.util.Processor;
29 import org.jetbrains.annotations.NotNull;
31 import javax.swing.*;
32 import java.util.ArrayList;
33 import java.util.Collection;
34 import java.util.Collections;
35 import java.util.List;
37 /**
38 * @author cdr
40 public class SliceNode extends AbstractTreeNode<SliceUsage> implements DuplicateNodeRenderer.DuplicatableNode<SliceNode>, MyColoredTreeCellRenderer {
41 protected List<SliceNode> myCachedChildren;
42 protected boolean initialized;
43 protected SliceNode duplicate;
44 protected final DuplicateMap targetEqualUsages;
45 protected boolean changed;
46 private int index; // my index in parent's mycachedchildren
48 protected SliceNode(@NotNull Project project, SliceUsage sliceUsage, @NotNull DuplicateMap targetEqualUsages) {
49 super(project, sliceUsage);
50 this.targetEqualUsages = targetEqualUsages;
53 SliceNode copy() {
54 SliceUsage newUsage = getValue().copy();
55 SliceNode newNode = new SliceNode(getProject(), newUsage, targetEqualUsages);
56 newNode.initialized = initialized;
57 newNode.duplicate = duplicate;
58 return newNode;
61 @NotNull
62 public Collection<? extends AbstractTreeNode> getChildren() {
63 ProgressIndicator current = ProgressManager.getInstance().getProgressIndicator();
64 ProgressIndicator indicator = current == null ? new ProgressIndicatorBase() : current;
65 if (current == null) {
66 indicator.start();
68 final Collection[] nodes = new Collection[1];
69 ((ProgressManagerImpl)ProgressManager.getInstance()).executeProcessUnderProgress(new Runnable(){
70 public void run() {
71 nodes[0] = getChildrenUnderProgress(ProgressManager.getInstance().getProgressIndicator());
73 }, indicator);
74 if (current == null) {
75 indicator.stop();
77 return nodes[0];
80 SliceNode getNext(List parentChildren) {
81 return index == parentChildren.size() - 1 ? null : (SliceNode)parentChildren.get(index + 1);
84 SliceNode getPrev(List parentChildren) {
85 return index == 0 ? null : (SliceNode)parentChildren.get(index - 1);
88 protected List<? extends AbstractTreeNode> getChildrenUnderProgress(ProgressIndicator progress) {
89 if (isUpToDate()) return myCachedChildren == null ? Collections.<AbstractTreeNode>emptyList() : myCachedChildren;
90 final List<SliceNode> children = new ArrayList<SliceNode>();
91 final SliceManager manager = SliceManager.getInstance(getProject());
92 manager.runInterruptibly(new Runnable() {
93 public void run() {
94 Processor<SliceUsage> processor = new Processor<SliceUsage>() {
95 public boolean process(SliceUsage sliceUsage) {
96 manager.checkCanceled();
97 SliceNode node = new SliceNode(myProject, sliceUsage, targetEqualUsages);
98 synchronized (children) {
99 node.index = children.size();
100 children.add(node);
102 return true;
106 getValue().processChildren(processor);
108 }, new Runnable(){
109 public void run() {
110 changed = true;
111 //SwingUtilities.invokeLater(new Runnable() {
112 // public void run() {
113 // if (getTreeBuilder().isDisposed()) return;
114 // DefaultMutableTreeNode node = getTreeBuilder().getNodeForElement(getValue());
115 // //myTreeBuilder.getUi().queueBackgroundUpdate(node, (NodeDescriptor)node.getUserObject(), new TreeUpdatePass(node));
116 // if (node == null) node = getTreeBuilder().getRootNode();
117 // getTreeBuilder().addSubtreeToUpdate(node);
118 // }
119 //});
121 }, progress);
123 synchronized (children) {
124 myCachedChildren = children;
126 return children;
129 private boolean isUpToDate() {
130 if (myCachedChildren != null || !isValid()/* || getTreeBuilder().splitByLeafExpressions*/) {
131 return true;
133 return false;
136 @NotNull
137 @Override
138 protected PresentationData createPresentation() {
139 return new PresentationData(){
140 @Override
141 public Object[] getEqualityObjects() {
142 return ArrayUtil.append(super.getEqualityObjects(), changed);
147 protected void update(PresentationData presentation) {
148 if (!initialized) {
149 duplicate = targetEqualUsages.putNodeCheckDupe(this);
150 initialized = true;
152 if (presentation != null) {
153 presentation.setChanged(presentation.isChanged() || changed);
154 changed = false;
155 if (duplicate != null) {
156 presentation.setTooltip("Duplicate node");
159 if (getValue() instanceof SliceDereferenceUsage) {
160 presentation.setTooltip("Variable dereferenced");
165 public SliceNode getDuplicate() {
166 return duplicate;
169 public void navigate(boolean requestFocus) {
170 SliceUsage sliceUsage = getValue();
171 sliceUsage.navigate(requestFocus);
174 public boolean canNavigate() {
175 return getValue().canNavigate();
178 public boolean canNavigateToSource() {
179 return getValue().canNavigateToSource();
182 public boolean isValid() {
183 return getValue().isValid();
186 public boolean expandOnDoubleClick() {
187 return false;
190 public void customizeCellRenderer(SliceUsageCellRenderer renderer, JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
191 renderer.setIcon(getPresentation().getIcon(expanded));
192 if (isValid()) {
193 SliceUsage sliceUsage = getValue();
194 renderer.customizeCellRendererFor(sliceUsage);
195 renderer.setToolTipText(sliceUsage.getPresentation().getTooltipText());
197 else {
198 renderer.append(UsageViewBundle.message("node.invalid") + " ", SliceUsageCellRenderer.ourInvalidAttributes);
202 public void setChanged() {
203 changed = true;
206 @Override
207 public String toString() {
208 return getValue()==null?"<null>":getValue().toString();