Hierarchy providers refactored
[fedora-idea.git] / lang-impl / src / com / intellij / ide / hierarchy / CallHierarchyBrowserBase.java
blob391828fceb8cd333b1902a376bbca34662ce491e
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;
13 import javax.swing.*;
14 import javax.swing.tree.DefaultMutableTreeNode;
15 import java.awt.*;
16 import java.util.HashMap;
17 import java.util.Map;
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);
41 @Nullable
42 protected JPanel createLegendPanel() {
43 return null;
46 protected abstract PsiElement getEnclosingElementFromNode(final DefaultMutableTreeNode node);
48 @NotNull
49 protected String getBrowserDataKey() {
50 return CALL_HIERARCHY_BROWSER_DATA_KEY;
53 @Override
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);
67 @NotNull
68 protected String getActionPlace() {
69 return ActionPlaces.CALL_HIERARCHY_VIEW_TOOLBAR;
72 @NotNull
73 protected String getPrevOccurenceActionNameImpl() {
74 return IdeBundle.message("hierarchy.call.prev.occurence.name");
77 @NotNull
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) {
100 if (flag) {
101 // setWaitCursor();
102 // invokeLater is called to update state of button before long tree building operation
103 ApplicationManager.getApplication().invokeLater(new Runnable() {
104 public void run() {
105 changeView(myTypeName);
111 public final void update(final AnActionEvent event) {
112 super.update(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());
132 @NotNull
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));
141 return group;
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));
150 return panel;
153 private final class MenuAction extends AnAction {
154 private final String myScopeType;
156 public MenuAction(final String scopeType) {
157 super(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() {
166 public void run() {
167 doRefresh(true); // scope is kept per type so other builders doesn't need to be refreshed