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.
17 package com
.intellij
.ide
.hierarchy
;
19 import com
.intellij
.ide
.IdeBundle
;
20 import com
.intellij
.openapi
.actionSystem
.*;
21 import com
.intellij
.openapi
.actionSystem
.ex
.ComboBoxAction
;
22 import com
.intellij
.openapi
.application
.ApplicationManager
;
23 import com
.intellij
.openapi
.project
.Project
;
24 import com
.intellij
.openapi
.util
.IconLoader
;
25 import com
.intellij
.psi
.PsiElement
;
26 import org
.jetbrains
.annotations
.NotNull
;
27 import org
.jetbrains
.annotations
.Nullable
;
30 import javax
.swing
.tree
.DefaultMutableTreeNode
;
32 import java
.util
.HashMap
;
35 public abstract class CallHierarchyBrowserBase
extends HierarchyBrowserBaseEx
{
37 @SuppressWarnings({"UnresolvedPropertyKey"})
38 public static final String CALLEE_TYPE
= IdeBundle
.message("title.hierarchy.callees.of");
39 @SuppressWarnings({"UnresolvedPropertyKey"})
40 public static final String CALLER_TYPE
= IdeBundle
.message("title.hierarchy.callers.of");
42 public static final String SCOPE_PROJECT
= IdeBundle
.message("hierarchy.scope.project");
43 static final String SCOPE_ALL
= IdeBundle
.message("hierarchy.scope.all");
44 public static final String SCOPE_TEST
= IdeBundle
.message("hierarchy.scope.test");
45 public static final String SCOPE_CLASS
= IdeBundle
.message("hierarchy.scope.this.class");
47 private final Map
<String
, String
> myType2ScopeMap
= new HashMap
<String
, String
>();
49 private static final String CALL_HIERARCHY_BROWSER_DATA_KEY
= "com.intellij.ide.hierarchy.CallHierarchyBrowserBase";
51 public CallHierarchyBrowserBase(final Project project
, final PsiElement method
) {
52 super(project
, method
);
54 for (String type
: myType2TreeMap
.keySet()) {
55 myType2ScopeMap
.put(type
, SCOPE_ALL
);
60 protected JPanel
createLegendPanel() {
64 protected abstract PsiElement
getEnclosingElementFromNode(final DefaultMutableTreeNode node
);
67 protected String
getBrowserDataKey() {
68 return CALL_HIERARCHY_BROWSER_DATA_KEY
;
71 protected void prependActions(@NotNull DefaultActionGroup actionGroup
) {
72 actionGroup
.add(new ChangeViewTypeActionBase(IdeBundle
.message("action.caller.methods.hierarchy"),
73 IdeBundle
.message("action.caller.methods.hierarchy"),
74 IconLoader
.getIcon("/hierarchy/caller.png"), CALLER_TYPE
));
75 actionGroup
.add(new ChangeViewTypeActionBase(IdeBundle
.message("action.callee.methods.hierarchy"),
76 IdeBundle
.message("action.callee.methods.hierarchy"),
77 IconLoader
.getIcon("/hierarchy/callee.png"), CALLEE_TYPE
));
78 actionGroup
.add(new AlphaSortAction());
79 actionGroup
.add(new ChangeScopeAction());
83 protected String
getActionPlace() {
84 return ActionPlaces
.CALL_HIERARCHY_VIEW_TOOLBAR
;
88 protected String
getPrevOccurenceActionNameImpl() {
89 return IdeBundle
.message("hierarchy.call.prev.occurence.name");
93 protected String
getNextOccurenceActionNameImpl() {
94 return IdeBundle
.message("hierarchy.call.next.occurence.name");
97 protected String
getCurrentScopeType() {
98 if (myCurrentViewType
== null) return null;
99 return myType2ScopeMap
.get(myCurrentViewType
);
102 private class ChangeViewTypeActionBase
extends ToggleAction
{
103 private final String myTypeName
;
105 public ChangeViewTypeActionBase(final String shortDescription
, final String longDescription
, final Icon icon
, String typeName
) {
106 super(shortDescription
, longDescription
, icon
);
107 myTypeName
= typeName
;
110 public final boolean isSelected(final AnActionEvent event
) {
111 return myTypeName
.equals(myCurrentViewType
);
114 public final void setSelected(final AnActionEvent event
, final boolean flag
) {
117 // invokeLater is called to update state of button before long tree building operation
118 ApplicationManager
.getApplication().invokeLater(new Runnable() {
120 changeView(myTypeName
);
126 public final void update(final AnActionEvent event
) {
128 setEnabled(isValidBase());
132 protected static class BaseOnThisMethodAction
extends BaseOnThisElementAction
{
133 public BaseOnThisMethodAction() {
134 super(IdeBundle
.message("action.base.on.this.method"), IdeActions
.ACTION_CALL_HIERARCHY
, CALL_HIERARCHY_BROWSER_DATA_KEY
);
138 private final class ChangeScopeAction
extends ComboBoxAction
{
139 public final void update(final AnActionEvent e
) {
140 final Presentation presentation
= e
.getPresentation();
141 final Project project
= PlatformDataKeys
.PROJECT
.getData(e
.getDataContext());
142 if (project
== null) return;
144 presentation
.setText(getCurrentScopeType());
148 protected final DefaultActionGroup
createPopupActionGroup(final JComponent button
) {
149 final DefaultActionGroup group
= new DefaultActionGroup();
151 group
.add(new MenuAction(SCOPE_PROJECT
));
152 group
.add(new MenuAction(SCOPE_TEST
));
153 group
.add(new MenuAction(SCOPE_ALL
));
154 group
.add(new MenuAction(SCOPE_CLASS
));
159 public final JComponent
createCustomComponent(final Presentation presentation
) {
160 final JPanel panel
= new JPanel(new GridBagLayout());
161 panel
.add(new JLabel(IdeBundle
.message("label.scope")),
162 new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints
.WEST
, GridBagConstraints
.BOTH
, new Insets(0, 5, 0, 0), 0, 0));
163 panel
.add(super.createCustomComponent(presentation
),
164 new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints
.WEST
, GridBagConstraints
.BOTH
, new Insets(0, 0, 0, 0), 0, 0));
168 private final class MenuAction
extends AnAction
{
169 private final String myScopeType
;
171 public MenuAction(final String scopeType
) {
173 myScopeType
= scopeType
;
176 public final void actionPerformed(final AnActionEvent e
) {
177 myType2ScopeMap
.put(myCurrentViewType
, myScopeType
);
179 // invokeLater is called to update state of button before long tree building operation
180 ApplicationManager
.getApplication().invokeLater(new Runnable() {
182 doRefresh(true); // scope is kept per type so other builders doesn't need to be refreshed