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.actions.CloseTabToolbarAction;
20 import com.intellij.ide.actions.ContextHelpAction;
21 import com.intellij.openapi.Disposable;
22 import com.intellij.openapi.actionSystem.*;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.ui.SimpleToolWindowPanel;
25 import com.intellij.pom.Navigatable;
26 import com.intellij.psi.NavigatablePsiElement;
27 import com.intellij.psi.PsiElement;
28 import com.intellij.ui.AutoScrollToSourceHandler;
29 import com.intellij.ui.TreeSpeedSearch;
30 import com.intellij.ui.TreeToolTipHandler;
31 import com.intellij.ui.content.Content;
32 import com.intellij.ui.content.tabs.PinToolwindowTabAction;
33 import com.intellij.ui.treeStructure.Tree;
34 import com.intellij.util.ui.UIUtil;
35 import com.intellij.util.ui.tree.TreeUtil;
36 import org.jetbrains.annotations.NonNls;
37 import org.jetbrains.annotations.NotNull;
38 import org.jetbrains.annotations.Nullable;
41 import javax.swing.tree.DefaultMutableTreeNode;
42 import javax.swing.tree.TreePath;
43 import javax.swing.tree.TreeSelectionModel;
44 import java.util.ArrayList;
49 public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel implements HierarchyBrowser, Disposable, DataProvider {
50 private static final HierarchyNodeDescriptor[] EMPTY_DESCRIPTORS = new HierarchyNodeDescriptor[0];
52 protected Content myContent;
53 private final AutoScrollToSourceHandler myAutoScrollToSourceHandler;
54 protected final Project myProject;
56 protected HierarchyBrowserBase(Project project) {
59 myAutoScrollToSourceHandler = new AutoScrollToSourceHandler() {
61 protected boolean isAutoScrollMode() {
62 return HierarchyBrowserManager.getInstance(myProject).getState().IS_AUTOSCROLL_TO_SOURCE;
65 protected void setAutoScrollMode(final boolean state) {
66 HierarchyBrowserManager.getInstance(myProject).getState().IS_AUTOSCROLL_TO_SOURCE = state;
71 public void setContent(final Content content) {
75 public JComponent getComponent() {
79 protected void buildUi(JComponent toolbar, JComponent content) {
84 public void dispose() {
87 protected ActionToolbar createToolbar(final String place, final String helpID) {
88 final DefaultActionGroup actionGroup = new DefaultActionGroup();
89 appendActions(actionGroup, helpID);
90 final ActionToolbar actionToolbar = ActionManager.getInstance().createActionToolbar(place, actionGroup, true);
91 actionToolbar.setTargetComponent(this);
95 protected void appendActions(@NotNull DefaultActionGroup actionGroup, @Nullable String helpID) {
96 actionGroup.add(myAutoScrollToSourceHandler.createToggleAction());
97 actionGroup.add(PinToolwindowTabAction.getPinAction());
98 actionGroup.add(new CloseAction());
100 actionGroup.add(new ContextHelpAction(helpID));
104 protected abstract JTree getCurrentTree();
107 protected abstract PsiElement getElementFromDescriptor(@NotNull HierarchyNodeDescriptor descriptor);
110 protected DefaultMutableTreeNode getSelectedNode() {
111 final JTree tree = getCurrentTree();
112 if (tree == null) return null;
113 final TreePath path = tree.getSelectionPath();
114 if (path == null) return null;
115 final Object lastPathComponent = path.getLastPathComponent();
116 if (!(lastPathComponent instanceof DefaultMutableTreeNode)) return null;
117 return (DefaultMutableTreeNode)lastPathComponent;
121 protected final PsiElement getSelectedElement() {
122 final DefaultMutableTreeNode node = getSelectedNode();
123 final HierarchyNodeDescriptor descriptor = node != null ? getDescriptor(node) : null;
124 return descriptor != null ? getElementFromDescriptor(descriptor) : null;
128 protected HierarchyNodeDescriptor getDescriptor(DefaultMutableTreeNode node) {
129 final Object userObject = node != null ? node.getUserObject() : null;
130 if (userObject instanceof HierarchyNodeDescriptor) {
131 return (HierarchyNodeDescriptor)userObject;
136 public final HierarchyNodeDescriptor[] getSelectedDescriptors() {
137 final JTree tree = getCurrentTree();
139 return EMPTY_DESCRIPTORS;
141 final TreePath[] paths = tree.getSelectionPaths();
142 if (paths == null || paths.length == 0) {
143 return EMPTY_DESCRIPTORS;
145 final ArrayList<HierarchyNodeDescriptor> list = new ArrayList<HierarchyNodeDescriptor>(paths.length);
146 for (final TreePath path : paths) {
147 final Object lastPathComponent = path.getLastPathComponent();
148 if (lastPathComponent instanceof DefaultMutableTreeNode) {
149 final DefaultMutableTreeNode node = (DefaultMutableTreeNode)lastPathComponent;
150 HierarchyNodeDescriptor descriptor = getDescriptor(node);
151 if (descriptor != null) {
152 list.add(descriptor);
156 return list.toArray(new HierarchyNodeDescriptor[list.size()]);
159 private PsiElement[] getSelectedElements() {
160 HierarchyNodeDescriptor[] descriptors = getSelectedDescriptors();
161 ArrayList<PsiElement> elements = new ArrayList<PsiElement>();
162 for (HierarchyNodeDescriptor descriptor : descriptors) {
163 PsiElement element = getElementFromDescriptor(descriptor);
164 if (element != null) elements.add(element);
166 return elements.toArray(new PsiElement[elements.size()]);
170 private Navigatable[] getNavigatables() {
171 final HierarchyNodeDescriptor[] selectedDescriptors = getSelectedDescriptors();
172 if (selectedDescriptors == null || selectedDescriptors.length == 0) return null;
173 final ArrayList<Navigatable> result = new ArrayList<Navigatable>();
174 for (HierarchyNodeDescriptor descriptor : selectedDescriptors) {
175 Navigatable navigatable = getNavigatable(descriptor);
176 if (navigatable != null) {
177 result.add(navigatable);
180 return result.toArray(new Navigatable[result.size()]);
183 private Navigatable getNavigatable(HierarchyNodeDescriptor descriptor) {
184 if (descriptor instanceof Navigatable && descriptor.isValid()) {
185 return (Navigatable)descriptor;
188 PsiElement element = getElementFromDescriptor(descriptor);
189 if (element instanceof NavigatablePsiElement && element.isValid()) {
190 return (NavigatablePsiElement)element;
196 public Object getData(@NonNls final String dataId) {
197 if (LangDataKeys.PSI_ELEMENT.is(dataId)) {
198 final PsiElement anElement = getSelectedElement();
199 return anElement != null && anElement.isValid() ? anElement : null;
201 if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
202 return getSelectedElements();
204 if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
207 if (PlatformDataKeys.NAVIGATABLE.is(dataId)) {
208 final DefaultMutableTreeNode selectedNode = getSelectedNode();
209 if (selectedNode == null) return null;
210 final HierarchyNodeDescriptor descriptor = getDescriptor(selectedNode);
211 if (descriptor == null) return null;
212 return getNavigatable(descriptor);
214 if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) {
215 return getNavigatables();
220 private final class CloseAction extends CloseTabToolbarAction {
221 public final void actionPerformed(final AnActionEvent e) {
222 myContent.getManager().removeContent(myContent, true);
226 protected void configureTree(Tree tree) {
227 tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
228 tree.setToggleClickCount(-1);
229 tree.setCellRenderer(new HierarchyNodeRenderer());
230 UIUtil.setLineStyleAngled(tree);
231 new TreeSpeedSearch(tree);
232 TreeUtil.installActions(tree);
233 TreeToolTipHandler.install(tree);
234 myAutoScrollToSourceHandler.install(tree);