update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / ide / hierarchy / method / MethodHierarchyNodeDescriptor.java
blob4865a9d8b62f1a816b8b6b0b16db12a190fec4fa
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.ide.hierarchy.method;
18 import com.intellij.ide.IdeBundle;
19 import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
20 import com.intellij.ide.hierarchy.JavaHierarchyUtil;
21 import com.intellij.openapi.editor.markup.TextAttributes;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.openapi.roots.ui.util.CompositeAppearance;
24 import com.intellij.openapi.util.Comparing;
25 import com.intellij.openapi.util.IconLoader;
26 import com.intellij.openapi.util.Iconable;
27 import com.intellij.psi.PsiClass;
28 import com.intellij.psi.PsiElement;
29 import com.intellij.psi.PsiMethod;
30 import com.intellij.psi.PsiModifier;
31 import com.intellij.psi.presentation.java.ClassPresentationUtil;
32 import com.intellij.ui.LayeredIcon;
33 import com.intellij.ui.RowIcon;
35 import javax.swing.*;
36 import java.awt.*;
38 public final class MethodHierarchyNodeDescriptor extends HierarchyNodeDescriptor {
39 private static final Icon METHOD_DEFINED_ICON = IconLoader.getIcon("/hierarchy/methodDefined.png");
40 private static final Icon METHOD_NOT_DEFINED_ICON = IconLoader.getIcon("/hierarchy/methodNotDefined.png");
41 private static final Icon SHOULD_DEFINE_METHOD_ICON = IconLoader.getIcon("/hierarchy/shouldDefineMethod.png");
43 private Icon myRawIcon;
44 private Icon myStateIcon;
45 private MethodHierarchyTreeStructure myTreeStructure;
47 public MethodHierarchyNodeDescriptor(
48 final Project project,
49 final HierarchyNodeDescriptor parentDescriptor,
50 final PsiClass aClass,
51 final boolean isBase,
52 final MethodHierarchyTreeStructure treeStructure
54 super(project, parentDescriptor, aClass, isBase);
55 myTreeStructure = treeStructure;
58 public final void setTreeStructure(final MethodHierarchyTreeStructure treeStructure) {
59 myTreeStructure = treeStructure;
62 private PsiMethod getMethod(final PsiClass aClass, final boolean checkBases) {
63 return MethodHierarchyUtil.findBaseMethodInClass(myTreeStructure.getBaseMethod(), aClass, checkBases);
66 public final PsiClass getPsiClass() {
67 return (PsiClass)myElement;
70 /**
71 * Element for OpenFileDescriptor
73 public final PsiElement getTargetElement() {
74 final PsiClass aClass = getPsiClass();
75 if (aClass == null || !aClass.isValid()) return null;
76 final PsiMethod method = getMethod(aClass, false);
77 if (method != null) return method;
78 return aClass;
81 public final boolean isValid() {
82 final PsiClass aClass = getPsiClass();
83 return aClass != null && aClass.isValid();
86 public final boolean update() {
87 int flags = Iconable.ICON_FLAG_VISIBILITY;
88 if (isMarkReadOnly()){
89 flags |= Iconable.ICON_FLAG_READ_STATUS;
92 boolean changes = super.update();
94 final PsiClass psiClass = getPsiClass();
96 if (psiClass == null){
97 final String invalidPrefix = IdeBundle.message("node.hierarchy.invalid");
98 if (!myHighlightedText.getText().startsWith(invalidPrefix)) {
99 myHighlightedText.getBeginning().addText(invalidPrefix, HierarchyNodeDescriptor.getInvalidPrefixAttributes());
101 return true;
104 final Icon newRawIcon = psiClass.getIcon(flags);
105 final Icon newStateIcon = calculateState(psiClass);
107 if (newRawIcon != myRawIcon || newStateIcon != myStateIcon) {
108 changes = true;
110 myRawIcon = newRawIcon;
111 myStateIcon = newStateIcon;
113 myOpenIcon = myRawIcon;
115 if (myIsBase) {
116 final LayeredIcon icon = new LayeredIcon(2);
117 icon.setIcon(myOpenIcon, 0);
118 icon.setIcon(BASE_POINTER_ICON, 1, -BASE_POINTER_ICON.getIconWidth() / 2, 0);
119 myOpenIcon = icon;
122 if (myStateIcon != null) {
123 final RowIcon icon = new RowIcon(2);
124 icon.setIcon(myStateIcon, 0);
125 icon.setIcon(myOpenIcon, 1);
126 myOpenIcon = icon;
129 myClosedIcon = myOpenIcon;
132 final CompositeAppearance oldText = myHighlightedText;
134 myHighlightedText = new CompositeAppearance();
135 TextAttributes classNameAttributes = null;
136 if (myColor != null) {
137 classNameAttributes = new TextAttributes(myColor, null, null, null, Font.PLAIN);
139 myHighlightedText.getEnding().addText(ClassPresentationUtil.getNameForClass(psiClass, false), classNameAttributes);
140 myHighlightedText.getEnding().addText(" (" + JavaHierarchyUtil.getPackageName(psiClass) + ")", HierarchyNodeDescriptor.getPackageNameAttributes());
141 myName = myHighlightedText.getText();
143 if (!Comparing.equal(myHighlightedText, oldText)) {
144 changes = true;
146 return changes;
149 private Icon calculateState(final PsiClass psiClass) {
150 final PsiMethod method = getMethod(psiClass, false);
151 if (method != null) {
152 if (method.hasModifierProperty(PsiModifier.ABSTRACT)) {
153 return null;
155 return METHOD_DEFINED_ICON;
158 if (myTreeStructure.isSuperClassForBaseClass(psiClass)) {
159 return METHOD_NOT_DEFINED_ICON;
162 final boolean isAbstractClass = psiClass.hasModifierProperty(PsiModifier.ABSTRACT);
164 // was it implemented is in superclasses?
165 final PsiMethod baseClassMethod = getMethod(psiClass, true);
167 final boolean hasBaseImplementation = baseClassMethod != null && !baseClassMethod.hasModifierProperty(PsiModifier.ABSTRACT);
169 if (hasBaseImplementation || isAbstractClass) {
170 return METHOD_NOT_DEFINED_ICON;
172 else {
173 return SHOULD_DEFINE_METHOD_ICON;