1 package com
.intellij
.ide
.hierarchy
;
3 import com
.intellij
.ide
.IdeBundle
;
4 import com
.intellij
.openapi
.actionSystem
.*;
5 import com
.intellij
.openapi
.actionSystem
.ex
.ComboBoxAction
;
6 import com
.intellij
.openapi
.application
.ApplicationManager
;
7 import com
.intellij
.openapi
.project
.Project
;
8 import com
.intellij
.openapi
.util
.IconLoader
;
9 import com
.intellij
.psi
.PsiElement
;
10 import org
.jetbrains
.annotations
.NotNull
;
11 import org
.jetbrains
.annotations
.Nullable
;
14 import javax
.swing
.tree
.DefaultMutableTreeNode
;
16 import java
.util
.HashMap
;
19 public abstract class CallHierarchyBrowserBase
extends HierarchyBrowserBaseEx
{
21 public static final String CALLEE_TYPE
= IdeBundle
.message("title.hierarchy.callees.of");
22 public static final String CALLER_TYPE
= IdeBundle
.message("title.hierarchy.callers.of");
24 public static final String SCOPE_PROJECT
= IdeBundle
.message("hierarchy.scope.project");
25 static final String SCOPE_ALL
= IdeBundle
.message("hierarchy.scope.all");
26 public static final String SCOPE_TEST
= IdeBundle
.message("hierarchy.scope.test");
27 public static final String SCOPE_CLASS
= IdeBundle
.message("hierarchy.scope.this.class");
29 private final Map
<String
, String
> myType2ScopeMap
= new HashMap
<String
, String
>();
31 private static final String CALL_HIERARCHY_BROWSER_DATA_KEY
= "com.intellij.ide.hierarchy.CallHierarchyBrowserBase";
33 public CallHierarchyBrowserBase(final Project project
, final PsiElement method
) {
34 super(project
, method
);
36 for (String type
: myType2TreeMap
.keySet()) {
37 myType2ScopeMap
.put(type
, SCOPE_ALL
);
42 protected JPanel
createLegendPanel() {
46 protected abstract PsiElement
getEnclosingElementFromNode(final DefaultMutableTreeNode node
);
49 protected String
getBrowserDataKey() {
50 return CALL_HIERARCHY_BROWSER_DATA_KEY
;
54 protected void appendActions(@NotNull DefaultActionGroup actionGroup
, String helpID
) {
55 actionGroup
.add(new ChangeViewTypeActionBase(IdeBundle
.message("action.caller.methods.hierarchy"),
56 IdeBundle
.message("action.caller.methods.hierarchy"),
57 IconLoader
.getIcon("/hierarchy/caller.png"), CALLER_TYPE
));
58 actionGroup
.add(new ChangeViewTypeActionBase(IdeBundle
.message("action.callee.methods.hierarchy"),
59 IdeBundle
.message("action.callee.methods.hierarchy"),
60 IconLoader
.getIcon("/hierarchy/callee.png"), CALLEE_TYPE
));
61 actionGroup
.add(new AlphaSortAction());
62 actionGroup
.add(new ChangeScopeAction());
64 super.appendActions(actionGroup
, helpID
);
68 protected String
getActionPlace() {
69 return ActionPlaces
.CALL_HIERARCHY_VIEW_TOOLBAR
;
73 protected String
getPrevOccurenceActionNameImpl() {
74 return IdeBundle
.message("hierarchy.call.prev.occurence.name");
78 protected String
getNextOccurenceActionNameImpl() {
79 return IdeBundle
.message("hierarchy.call.next.occurence.name");
82 protected String
getCurrentScopeType() {
83 if (myCurrentViewType
== null) return null;
84 return myType2ScopeMap
.get(myCurrentViewType
);
87 private class ChangeViewTypeActionBase
extends ToggleAction
{
88 private final String myTypeName
;
90 public ChangeViewTypeActionBase(final String shortDescription
, final String longDescription
, final Icon icon
, String typeName
) {
91 super(shortDescription
, longDescription
, icon
);
92 myTypeName
= typeName
;
95 public final boolean isSelected(final AnActionEvent event
) {
96 return myTypeName
.equals(myCurrentViewType
);
99 public final void setSelected(final AnActionEvent event
, final boolean flag
) {
102 // invokeLater is called to update state of button before long tree building operation
103 ApplicationManager
.getApplication().invokeLater(new Runnable() {
105 changeView(myTypeName
);
111 public final void update(final AnActionEvent event
) {
113 setEnabled(isValidBase());
117 protected static class BaseOnThisMethodAction
extends BaseOnThisElementAction
{
118 public BaseOnThisMethodAction() {
119 super(IdeBundle
.message("action.base.on.this.method"), IdeActions
.ACTION_CALL_HIERARCHY
, CALL_HIERARCHY_BROWSER_DATA_KEY
);
123 private final class ChangeScopeAction
extends ComboBoxAction
{
124 public final void update(final AnActionEvent e
) {
125 final Presentation presentation
= e
.getPresentation();
126 final Project project
= PlatformDataKeys
.PROJECT
.getData(e
.getDataContext());
127 if (project
== null) return;
129 presentation
.setText(getCurrentScopeType());
133 protected final DefaultActionGroup
createPopupActionGroup(final JComponent button
) {
134 final DefaultActionGroup group
= new DefaultActionGroup();
136 group
.add(new MenuAction(SCOPE_PROJECT
));
137 group
.add(new MenuAction(SCOPE_TEST
));
138 group
.add(new MenuAction(SCOPE_ALL
));
139 group
.add(new MenuAction(SCOPE_CLASS
));
144 public final JComponent
createCustomComponent(final Presentation presentation
) {
145 final JPanel panel
= new JPanel(new GridBagLayout());
146 panel
.add(new JLabel(IdeBundle
.message("label.scope")),
147 new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints
.WEST
, GridBagConstraints
.BOTH
, new Insets(0, 5, 0, 0), 0, 0));
148 panel
.add(super.createCustomComponent(presentation
),
149 new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints
.WEST
, GridBagConstraints
.BOTH
, new Insets(0, 0, 0, 0), 0, 0));
153 private final class MenuAction
extends AnAction
{
154 private final String myScopeType
;
156 public MenuAction(final String scopeType
) {
158 myScopeType
= scopeType
;
161 public final void actionPerformed(final AnActionEvent e
) {
162 myType2ScopeMap
.put(myCurrentViewType
, myScopeType
);
164 // invokeLater is called to update state of button before long tree building operation
165 ApplicationManager
.getApplication().invokeLater(new Runnable() {
167 doRefresh(true); // scope is kept per type so other builders doesn't need to be refreshed