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
;
32 import java
.util
.ArrayList
;
33 import java
.util
.Collection
;
34 import java
.util
.Collections
;
35 import java
.util
.List
;
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
;
54 SliceUsage newUsage
= getValue().copy();
55 SliceNode newNode
= new SliceNode(getProject(), newUsage
, targetEqualUsages
);
56 newNode
.initialized
= initialized
;
57 newNode
.duplicate
= duplicate
;
62 public Collection
<?
extends AbstractTreeNode
> getChildren() {
63 ProgressIndicator current
= ProgressManager
.getInstance().getProgressIndicator();
64 ProgressIndicator indicator
= current
== null ?
new ProgressIndicatorBase() : current
;
65 if (current
== null) {
68 final Collection
[] nodes
= new Collection
[1];
69 ((ProgressManagerImpl
)ProgressManager
.getInstance()).executeProcessUnderProgress(new Runnable(){
71 nodes
[0] = getChildrenUnderProgress(ProgressManager
.getInstance().getProgressIndicator());
74 if (current
== null) {
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() {
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();
106 getValue().processChildren(processor
);
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);
123 synchronized (children
) {
124 myCachedChildren
= children
;
129 private boolean isUpToDate() {
130 if (myCachedChildren
!= null || !isValid()/* || getTreeBuilder().splitByLeafExpressions*/) {
138 protected PresentationData
createPresentation() {
139 return new PresentationData(){
141 public Object
[] getEqualityObjects() {
142 return ArrayUtil
.append(super.getEqualityObjects(), changed
);
147 protected void update(PresentationData presentation
) {
149 if (!(getValue() instanceof SliceTooComplexDFAUsage
)) duplicate
= targetEqualUsages
.putNodeCheckDupe(this);
152 if (presentation
!= null) {
153 if (duplicate
!= null) {
154 presentation
.setTooltip("Duplicate node");
156 presentation
.setChanged(presentation
.isChanged() || changed
);
161 public SliceNode
getDuplicate() {
165 public void navigate(boolean requestFocus
) {
166 SliceUsage sliceUsage
= getValue();
167 sliceUsage
.navigate(requestFocus
);
170 public boolean canNavigate() {
171 return getValue().canNavigate();
174 public boolean canNavigateToSource() {
175 return getValue().canNavigateToSource();
178 public boolean isValid() {
179 return getValue().isValid();
182 public boolean expandOnDoubleClick() {
186 public void customizeCellRenderer(SliceUsageCellRenderer renderer
, JTree tree
, Object value
, boolean selected
, boolean expanded
, boolean leaf
, int row
, boolean hasFocus
) {
187 renderer
.setIcon(getPresentation().getIcon(expanded
));
189 SliceUsage sliceUsage
= getValue();
190 renderer
.customizeCellRendererFor(sliceUsage
);
191 renderer
.setToolTipText(sliceUsage
.getPresentation().getTooltipText());
194 renderer
.append(UsageViewBundle
.message("node.invalid") + " ", SliceUsageCellRenderer
.ourInvalidAttributes
);
198 public void setChanged() {
203 public String
toString() {
204 return getValue()==null?
"<null>":getValue().toString();