Hierarchy providers refactored
[fedora-idea.git] / lang-impl / src / com / intellij / ide / hierarchy / HierarchyBrowserBase.java
blobd93f26a486d2a9fb93c3a330af34eec43d9faaec
1 package com.intellij.ide.hierarchy;
3 import com.intellij.ide.actions.CloseTabToolbarAction;
4 import com.intellij.ide.actions.ContextHelpAction;
5 import com.intellij.openapi.Disposable;
6 import com.intellij.openapi.project.Project;
7 import com.intellij.openapi.actionSystem.*;
8 import com.intellij.openapi.ui.SimpleToolWindowPanel;
9 import com.intellij.pom.Navigatable;
10 import com.intellij.psi.NavigatablePsiElement;
11 import com.intellij.psi.PsiElement;
12 import com.intellij.ui.content.Content;
13 import com.intellij.ui.AutoScrollToSourceHandler;
14 import com.intellij.ui.TreeSpeedSearch;
15 import com.intellij.ui.TreeToolTipHandler;
16 import com.intellij.ui.treeStructure.Tree;
17 import com.intellij.util.ui.UIUtil;
18 import com.intellij.util.ui.tree.TreeUtil;
19 import org.jetbrains.annotations.NonNls;
20 import org.jetbrains.annotations.NotNull;
21 import org.jetbrains.annotations.Nullable;
23 import javax.swing.*;
24 import javax.swing.tree.DefaultMutableTreeNode;
25 import javax.swing.tree.TreePath;
26 import javax.swing.tree.TreeSelectionModel;
27 import java.util.ArrayList;
29 /**
30 * @author yole
32 public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel implements HierarchyBrowser, Disposable, DataProvider {
33 private static final HierarchyNodeDescriptor[] EMPTY_DESCRIPTORS = new HierarchyNodeDescriptor[0];
35 protected Content myContent;
36 private final AutoScrollToSourceHandler myAutoScrollToSourceHandler;
37 protected final Project myProject;
39 protected HierarchyBrowserBase(Project project) {
40 super(true, true);
41 myProject = project;
42 myAutoScrollToSourceHandler = new AutoScrollToSourceHandler() {
44 protected boolean isAutoScrollMode() {
45 return HierarchyBrowserManager.getInstance(myProject).getState().IS_AUTOSCROLL_TO_SOURCE;
48 protected void setAutoScrollMode(final boolean state) {
49 HierarchyBrowserManager.getInstance(myProject).getState().IS_AUTOSCROLL_TO_SOURCE = state;
54 public void setContent(final Content content) {
55 myContent = content;
58 public JComponent getComponent() {
59 return this;
62 protected void buildUi(JComponent toolbar, JComponent content) {
63 setToolbar(toolbar);
64 setContent(content);
67 public void dispose() {
70 protected ActionToolbar createToolbar(final String place, final String helpID) {
71 final DefaultActionGroup actionGroup = new DefaultActionGroup();
72 appendActions(actionGroup, helpID);
73 return ActionManager.getInstance().createActionToolbar(place, actionGroup, true);
76 protected void appendActions(@NotNull DefaultActionGroup actionGroup, @Nullable String helpID) {
77 actionGroup.add(myAutoScrollToSourceHandler.createToggleAction());
78 actionGroup.add(new CloseAction());
79 if (helpID != null) {
80 actionGroup.add(new ContextHelpAction(helpID));
84 protected abstract JTree getCurrentTree();
86 @Nullable
87 protected abstract PsiElement getElementFromDescriptor(@NotNull HierarchyNodeDescriptor descriptor);
89 protected DefaultMutableTreeNode getSelectedNode() {
90 final JTree tree = getCurrentTree();
91 if (tree == null) return null;
92 final TreePath path = tree.getSelectionPath();
93 if (path == null) return null;
94 final Object lastPathComponent = path.getLastPathComponent();
95 if (!(lastPathComponent instanceof DefaultMutableTreeNode)) return null;
96 return (DefaultMutableTreeNode)lastPathComponent;
99 protected final PsiElement getSelectedElement() {
100 final DefaultMutableTreeNode node = getSelectedNode();
101 HierarchyNodeDescriptor descriptor = getDescriptor(node);
102 return descriptor != null ? getElementFromDescriptor(descriptor) : null;
105 protected HierarchyNodeDescriptor getDescriptor(DefaultMutableTreeNode node) {
106 final Object userObject = node.getUserObject();
107 if (userObject instanceof HierarchyNodeDescriptor) {
108 return (HierarchyNodeDescriptor)userObject;
110 return null;
113 public final HierarchyNodeDescriptor[] getSelectedDescriptors() {
114 final JTree tree = getCurrentTree();
115 if (tree == null) {
116 return EMPTY_DESCRIPTORS;
118 final TreePath[] paths = tree.getSelectionPaths();
119 if (paths == null || paths.length == 0) {
120 return EMPTY_DESCRIPTORS;
122 final ArrayList<HierarchyNodeDescriptor> list = new ArrayList<HierarchyNodeDescriptor>(paths.length);
123 for (final TreePath path : paths) {
124 final Object lastPathComponent = path.getLastPathComponent();
125 if (lastPathComponent instanceof DefaultMutableTreeNode) {
126 final DefaultMutableTreeNode node = (DefaultMutableTreeNode)lastPathComponent;
127 HierarchyNodeDescriptor descriptor = getDescriptor(node);
128 if (descriptor != null) {
129 list.add(descriptor);
133 return list.toArray(new HierarchyNodeDescriptor[list.size()]);
136 private PsiElement[] getSelectedElements() {
137 HierarchyNodeDescriptor[] descriptors = getSelectedDescriptors();
138 ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
139 for (HierarchyNodeDescriptor descriptor : descriptors) {
140 PsiElement element = getElementFromDescriptor(descriptor);
141 if (element != null) elements.add(element);
143 return elements.toArray(new PsiElement[elements.size()]);
147 private Navigatable[] getNavigatables() {
148 final HierarchyNodeDescriptor[] selectedDescriptors = getSelectedDescriptors();
149 if (selectedDescriptors == null || selectedDescriptors.length == 0) return null;
150 final ArrayList<Navigatable> result = new ArrayList<Navigatable>();
151 for (HierarchyNodeDescriptor descriptor : selectedDescriptors) {
152 Navigatable navigatable = getNavigatable(descriptor);
153 if (navigatable != null) {
154 result.add(navigatable);
157 return result.toArray(new Navigatable[result.size()]);
160 private Navigatable getNavigatable(HierarchyNodeDescriptor descriptor) {
161 if (descriptor instanceof Navigatable && descriptor.isValid()) {
162 return (Navigatable)descriptor;
165 PsiElement element = getElementFromDescriptor(descriptor);
166 if (element instanceof NavigatablePsiElement && element.isValid()) {
167 return (NavigatablePsiElement)element;
169 return null;
172 @Nullable
173 public Object getData(@NonNls final String dataId) {
174 if (DataConstants.PSI_ELEMENT.equals(dataId)) {
175 final PsiElement anElement = getSelectedElement();
176 return anElement != null && anElement.isValid() ? anElement : null;
178 if (DataConstants.PSI_ELEMENT_ARRAY.equals(dataId)) {
179 return getSelectedElements();
181 if (DataConstants.DELETE_ELEMENT_PROVIDER.equals(dataId)) {
182 return null;
184 if (DataConstants.NAVIGATABLE.equals(dataId)) {
185 final DefaultMutableTreeNode selectedNode = getSelectedNode();
186 if (selectedNode == null) return null;
187 final HierarchyNodeDescriptor descriptor = getDescriptor(selectedNode);
188 if (descriptor == null) return null;
189 return getNavigatable(descriptor);
191 if (DataConstants.NAVIGATABLE_ARRAY.equals(dataId)) {
192 return getNavigatables();
194 return null;
197 private final class CloseAction extends CloseTabToolbarAction {
198 public final void actionPerformed(final AnActionEvent e) {
199 myContent.getManager().removeContent(myContent, true);
203 protected void configureTree(Tree tree) {
204 tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
205 tree.setToggleClickCount(-1);
206 tree.setCellRenderer(new HierarchyNodeRenderer());
207 UIUtil.setLineStyleAngled(tree);
208 new TreeSpeedSearch(tree);
209 TreeUtil.installActions(tree);
210 TreeToolTipHandler.install(tree);
211 myAutoScrollToSourceHandler.install(tree);