c7ae78f0cd5923edc848d881888f1198b9ac85e4
[idea/community.git] / platform / platform-impl / src / com / intellij / ide / actions / OccurenceNavigatorActionBase.java
1
2 /*
3  * Copyright 2000-2009 JetBrains s.r.o.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package com.intellij.ide.actions;
18
19 import com.intellij.ide.IdeBundle;
20 import com.intellij.ide.OccurenceNavigator;
21 import com.intellij.openapi.actionSystem.*;
22 import com.intellij.openapi.project.Project;
23 import com.intellij.openapi.project.DumbAware;
24 import com.intellij.openapi.util.Condition;
25 import com.intellij.openapi.wm.WindowManager;
26 import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
27 import com.intellij.openapi.wm.ex.WindowManagerEx;
28 import com.intellij.pom.Navigatable;
29 import com.intellij.ui.content.Content;
30 import com.intellij.ui.content.ContentManager;
31 import com.intellij.ui.content.ContentManagerUtil;
32 import org.jetbrains.annotations.Nullable;
33
34 import javax.swing.*;
35 import java.awt.*;
36 import java.util.LinkedList;
37
38 abstract class OccurenceNavigatorActionBase extends AnAction implements DumbAware {
39   public void actionPerformed(AnActionEvent e) {
40     Project project = CommonDataKeys.PROJECT.getData(e.getDataContext());
41     if (project == null) return;
42
43     OccurenceNavigator navigator = getNavigator(e.getDataContext());
44     if (navigator == null) {
45       return;
46     }
47     if (!hasOccurenceToGo(navigator)) {
48       return;
49     }
50     OccurenceNavigator.OccurenceInfo occurenceInfo = go(navigator);
51     if (occurenceInfo == null) {
52       return;
53     }
54     Navigatable descriptor = occurenceInfo.getNavigateable();
55     if (descriptor != null && descriptor.canNavigate()) {
56       descriptor.navigate(false);
57     }
58     if(occurenceInfo.getOccurenceNumber()==-1||occurenceInfo.getOccurencesCount()==-1){
59       return;
60     }
61     WindowManager.getInstance().getStatusBar(project).setInfo(
62       IdeBundle.message("message.occurrence.N.of.M", occurenceInfo.getOccurenceNumber(), occurenceInfo.getOccurencesCount()));
63   }
64
65   public void update(AnActionEvent event) {
66     Presentation presentation = event.getPresentation();
67     Project project = event.getData(CommonDataKeys.PROJECT);
68     if (project == null) {
69       presentation.setEnabled(false);
70       // make it invisible only in main menu to avoid initial invisibility in toolbars
71       presentation.setVisible(!ActionPlaces.isMainMenuOrActionSearch(event.getPlace()));
72       return;
73     }
74     OccurenceNavigator navigator = getNavigator(event.getDataContext());
75     if (navigator == null) {
76       presentation.setEnabled(false);
77       // make it invisible only in main menu to avoid initial invisibility in toolbars
78       presentation.setVisible(!ActionPlaces.isMainMenuOrActionSearch(event.getPlace()));
79       return;
80     }
81     presentation.setVisible(true);
82     presentation.setEnabled(hasOccurenceToGo(navigator));
83     presentation.setText(getDescription(navigator));
84   }
85
86   protected abstract OccurenceNavigator.OccurenceInfo go(OccurenceNavigator navigator);
87
88   protected abstract boolean hasOccurenceToGo(OccurenceNavigator navigator);
89
90   protected abstract String getDescription(OccurenceNavigator navigator);
91
92   @Nullable
93   protected OccurenceNavigator getNavigator(DataContext dataContext) {
94     ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(dataContext, false);
95     if (contentManager != null) {
96       Content content = contentManager.getSelectedContent();
97       if (content == null) return null;
98       JComponent component = content.getComponent();
99       return findNavigator(component);
100     }
101
102     return (OccurenceNavigator)getOccurenceNavigatorFromContext(dataContext);
103   }
104
105   @Nullable
106   private static OccurenceNavigator findNavigator(JComponent parent) {
107     LinkedList<JComponent> queue = new LinkedList<JComponent>();
108     queue.addLast(parent);
109     while (!queue.isEmpty()) {
110       JComponent component = queue.removeFirst();
111       if (component instanceof OccurenceNavigator) return (OccurenceNavigator)component;
112       if (component instanceof JTabbedPane) {
113         final JComponent selectedComponent = (JComponent)((JTabbedPane)component).getSelectedComponent();
114         if (selectedComponent != null) {
115           queue.addLast(selectedComponent);
116         }
117       }
118       else if (component != null){
119         for (int i = 0; i < component.getComponentCount(); i++) {
120           Component child = component.getComponent(i);
121           if (!(child instanceof JComponent)) continue;
122           queue.addLast((JComponent)child);
123         }
124       }
125     }
126     return null;
127   }
128
129   @Nullable
130   private static Component getOccurenceNavigatorFromContext(DataContext dataContext) {
131     Window window = WindowManagerEx.getInstanceEx().getMostRecentFocusedWindow();
132
133     if (window != null) {
134       Component component = window.getFocusOwner();
135       for (Component c = component; c != null; c = c.getParent()) {
136         if (c instanceof OccurenceNavigator) {
137           return c;
138         }
139       }
140     }
141
142     Project project = CommonDataKeys.PROJECT.getData(dataContext);
143     if (project == null) {
144       return null;
145     }
146
147     ToolWindowManagerEx mgr = ToolWindowManagerEx.getInstanceEx(project);
148
149     String id = mgr.getLastActiveToolWindowId(new Condition<JComponent>() {
150       public boolean value(final JComponent component) {
151         return findNavigator(component) != null;
152       }
153     });
154     if (id == null) {
155       return null;
156     }
157     return (Component)findNavigator(mgr.getToolWindow(id).getComponent());
158   }
159
160 }