IDEADEV-42139: new toggle button in the usage view "sort members alphabetically"
[fedora-idea.git] / java / java-impl / src / com / intellij / usages / impl / rules / MethodGroupingRule.java
blob09694b709f7ce942a57ef3f5137c1302414c7072
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.usages.impl.rules;
18 import com.intellij.openapi.actionSystem.DataKey;
19 import com.intellij.openapi.actionSystem.DataSink;
20 import com.intellij.openapi.actionSystem.LangDataKeys;
21 import com.intellij.openapi.actionSystem.TypeSafeDataProvider;
22 import com.intellij.openapi.diagnostic.Logger;
23 import com.intellij.openapi.util.Comparing;
24 import com.intellij.openapi.util.Iconable;
25 import com.intellij.openapi.vcs.FileStatus;
26 import com.intellij.psi.*;
27 import com.intellij.psi.util.PsiFormatUtil;
28 import com.intellij.psi.util.PsiTreeUtil;
29 import com.intellij.usageView.UsageInfo;
30 import com.intellij.usages.Usage;
31 import com.intellij.usages.UsageGroup;
32 import com.intellij.usages.UsageView;
33 import com.intellij.usages.UsageViewSettings;
34 import com.intellij.usages.rules.PsiElementUsage;
35 import com.intellij.usages.rules.UsageGroupingRule;
36 import org.jetbrains.annotations.NotNull;
38 import javax.swing.*;
40 /**
41 * @author max
43 public class MethodGroupingRule implements UsageGroupingRule {
44 private static final Logger LOG = Logger.getInstance("#com.intellij.usages.impl.rules.MethodGroupingRule");
46 public UsageGroup groupUsage(Usage usage) {
47 if (!(usage instanceof PsiElementUsage)) return null;
48 PsiElement psiElement = ((PsiElementUsage)usage).getElement();
49 if (psiElement.getContainingFile() instanceof PsiJavaFile) {
50 PsiElement containingMethod = psiElement;
51 do {
52 containingMethod = PsiTreeUtil.getParentOfType(containingMethod, PsiMethod.class, true);
53 if (containingMethod == null || ((PsiMethod)containingMethod).getContainingClass().getQualifiedName() != null) break;
55 while (true);
57 if (containingMethod != null) {
58 return new MethodUsageGroup((PsiMethod)containingMethod);
61 return null;
64 private static class MethodUsageGroup implements UsageGroup, TypeSafeDataProvider {
65 private final SmartPsiElementPointer<PsiMethod> myMethodPointer;
66 private final String myName;
67 private Icon myIcon;
69 public MethodUsageGroup(PsiMethod psiMethod) {
70 myName = PsiFormatUtil.formatMethod(
71 psiMethod,
72 PsiSubstitutor.EMPTY,
73 PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
74 PsiFormatUtil.SHOW_TYPE
76 myMethodPointer = SmartPointerManager.getInstance(psiMethod.getProject()).createLazyPointer(psiMethod);
77 update();
80 public void update() {
81 if (isValid()) {
82 myIcon = getIconImpl(getMethod());
86 private static Icon getIconImpl(PsiMethod psiMethod) {
87 return psiMethod.getIcon(Iconable.ICON_FLAG_VISIBILITY | Iconable.ICON_FLAG_READ_STATUS);
90 public int hashCode() {
91 return myName.hashCode();
94 public boolean equals(Object object) {
95 if (!(object instanceof MethodUsageGroup)) {
96 return false;
98 MethodUsageGroup group = (MethodUsageGroup) object;
99 if (isValid() && group.isValid()) {
100 return getMethod().getManager().areElementsEquivalent(getMethod(), group.getMethod());
102 return Comparing.equal(myName, ((MethodUsageGroup)object).myName);
105 public Icon getIcon(boolean isOpen) {
106 return myIcon;
109 private PsiMethod getMethod() {
110 return (PsiMethod)myMethodPointer.getElement();
113 @NotNull
114 public String getText(UsageView view) {
115 return myName;
118 public FileStatus getFileStatus() {
119 return isValid() ? getMethod().getFileStatus() : null;
122 public boolean isValid() {
123 final PsiMethod method = getMethod();
124 return method != null && method.isValid();
127 public void navigate(boolean focus) throws UnsupportedOperationException {
128 if (canNavigate()) {
129 getMethod().navigate(focus);
133 public boolean canNavigate() {
134 return isValid();
137 public boolean canNavigateToSource() {
138 return canNavigate();
141 public int compareTo(UsageGroup usageGroup) {
142 if (!(usageGroup instanceof MethodUsageGroup)) {
143 LOG.error("MethodUsageGroup expected but " + usageGroup.getClass() + " found");
145 MethodUsageGroup other = (MethodUsageGroup)usageGroup;
146 PsiMethod myMethod = myMethodPointer.getElement();
147 PsiMethod otherMethod = other.myMethodPointer.getElement();
148 if (myMethod != null && otherMethod != null && myMethod != otherMethod && !UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) {
149 return myMethod.getTextOffset() < otherMethod.getTextOffset() ? -1 : 1;
152 return myName.compareTo(other.myName);
155 public void calcData(final DataKey key, final DataSink sink) {
156 if (!isValid()) return;
157 if (LangDataKeys.PSI_ELEMENT == key) {
158 sink.put(LangDataKeys.PSI_ELEMENT, getMethod());
160 if (UsageView.USAGE_INFO_KEY == key) {
161 PsiMethod method = getMethod();
162 if (method != null) {
163 sink.put(UsageView.USAGE_INFO_KEY, new UsageInfo(method));