1f722849c513c5252221949214425e511280987a
[idea/community.git] / platform / platform-impl / src / com / intellij / ide / actions / ActivateToolWindowAction.java
1
2 /*
3  * Copyright 2000-2014 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.icons.AllIcons;
20 import com.intellij.ide.IdeBundle;
21 import com.intellij.notification.EventLog;
22 import com.intellij.openapi.actionSystem.*;
23 import com.intellij.openapi.keymap.Keymap;
24 import com.intellij.openapi.keymap.KeymapManager;
25 import com.intellij.openapi.project.DumbAwareAction;
26 import com.intellij.openapi.project.Project;
27 import com.intellij.openapi.wm.ToolWindow;
28 import com.intellij.openapi.wm.ToolWindowManager;
29 import com.intellij.openapi.wm.impl.ToolWindowImpl;
30 import com.intellij.ui.SizedIcon;
31 import com.intellij.ui.content.Content;
32 import org.jetbrains.annotations.NonNls;
33 import org.jetbrains.annotations.NotNull;
34
35 import javax.swing.*;
36 import java.awt.event.InputEvent;
37 import java.awt.event.KeyEvent;
38
39 /**
40  * Toggles tool window visibility.
41  * Usually shown in View|Tool-windows sub-menu.
42  * Dynamically registered in Settings|Keymap for each newly-registered tool window.
43  */
44 public class ActivateToolWindowAction extends DumbAwareAction {
45   private final String myToolWindowId;
46
47   private ActivateToolWindowAction(@NotNull String toolWindowId) {
48     myToolWindowId = toolWindowId;
49   }
50
51   @NotNull
52   public String getToolWindowId() {
53     return myToolWindowId;
54   }
55
56   public static void ensureToolWindowActionRegistered(@NotNull ToolWindowImpl toolWindow) {
57     ActionManager actionManager = ActionManager.getInstance();
58     String actionId = getActionIdForToolWindow(toolWindow.getId());
59     AnAction action = actionManager.getAction(actionId);
60     if (action == null) {
61       ActivateToolWindowAction newAction = new ActivateToolWindowAction(toolWindow.getId());
62       newAction.updatePresentation(newAction.getTemplatePresentation(), toolWindow);
63       actionManager.registerAction(actionId, newAction);
64     }
65   }
66
67   public static void updateToolWindowActionPresentation(@NotNull ToolWindowImpl toolWindow) {
68     ActionManager actionManager = ActionManager.getInstance();
69     String actionId = getActionIdForToolWindow(toolWindow.getId());
70     AnAction action = actionManager.getAction(actionId);
71     if (action instanceof ActivateToolWindowAction) {
72       ((ActivateToolWindowAction)action).updatePresentation(action.getTemplatePresentation(), toolWindow);
73     }
74   }
75
76   public void update(AnActionEvent e) {
77     Project project = getEventProject(e);
78     Presentation presentation = e.getPresentation();
79     if (project == null || project.isDisposed()) {
80       presentation.setEnabledAndVisible(false);
81       return;
82     }
83     ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow(myToolWindowId);
84     if (toolWindow == null) {
85       presentation.setEnabledAndVisible(false);
86     }
87     else {
88       presentation.setVisible(true);
89       presentation.setEnabled(toolWindow.isAvailable());
90       updatePresentation(presentation, toolWindow);
91     }
92   }
93
94   private void updatePresentation(@NotNull Presentation presentation, @NotNull ToolWindow toolWindow) {
95     String title = toolWindow.getStripeTitle();
96     presentation.setText(title);
97     presentation.setDescription(IdeBundle.message("action.activate.tool.window", title));
98     Icon icon = toolWindow.getIcon();
99     if (EventLog.LOG_TOOL_WINDOW_ID.equals(myToolWindowId)) {
100       icon = AllIcons.Ide.Notification.InfoEvents;
101     }
102     presentation.setIcon(icon == null ? null : new SizedIcon(icon, icon.getIconHeight(), icon.getIconHeight()));
103   }
104
105   public void actionPerformed(final AnActionEvent e) {
106     Project project = getEventProject(e);
107     if (project == null) return;
108     ToolWindowManager windowManager = ToolWindowManager.getInstance(project);
109     final ToolWindow window = windowManager.getToolWindow(myToolWindowId);
110     InputEvent event = e.getInputEvent();
111     Runnable run = null;
112     if (event instanceof KeyEvent && event.isShiftDown()) {
113       final Content[] contents = window.getContentManager().getContents();
114       if (contents.length > 0 && window.getContentManager().getSelectedContent() != contents[0]) {
115         run = () -> window.getContentManager().setSelectedContent(contents[0], true, true);
116       }
117     }
118
119     if (windowManager.isEditorComponentActive() || !myToolWindowId.equals(windowManager.getActiveToolWindowId()) || run != null) {
120       if (run != null && window.isActive()) {
121         run.run();
122       } else {
123         window.activate(run);
124       }
125     } else {
126       windowManager.getToolWindow(myToolWindowId).hide(null);
127     }
128   }
129
130   /**
131    * This is the "rule" method constructs <code>ID</code> of the action for activating tool window
132    * with specified <code>ID</code>.
133    *
134    * @param id <code>id</code> of tool window to be activated.
135    */
136   @NonNls
137   public static String getActionIdForToolWindow(String id) {
138     return "Activate" + id.replaceAll(" ", "") + "ToolWindow";
139   }
140
141   /**
142    * @return mnemonic for action if it has Alt+digit/Meta+digit shortcut.
143    * Otherwise the method returns <code>-1</code>. Meta mask is OK for
144    * Mac OS X user, because Alt+digit types strange characters into the
145    * editor.
146    */
147   public static int getMnemonicForToolWindow(String id) {
148     Keymap activeKeymap = KeymapManager.getInstance().getActiveKeymap();
149     Shortcut[] shortcuts = activeKeymap.getShortcuts(getActionIdForToolWindow(id));
150     for (Shortcut shortcut : shortcuts) {
151       if (shortcut instanceof KeyboardShortcut) {
152         KeyStroke keyStroke = ((KeyboardShortcut)shortcut).getFirstKeyStroke();
153         int modifiers = keyStroke.getModifiers();
154         if (
155           modifiers == (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_MASK) ||
156           modifiers == InputEvent.ALT_MASK ||
157           modifiers == InputEvent.ALT_DOWN_MASK ||
158           modifiers == (InputEvent.META_DOWN_MASK | InputEvent.META_MASK) ||
159           modifiers == InputEvent.META_MASK ||
160           modifiers == InputEvent.META_DOWN_MASK
161           ) {
162           int keyCode = keyStroke.getKeyCode();
163           if (KeyEvent.VK_0 <= keyCode && keyCode <= KeyEvent.VK_9) {
164             char c = (char)('0' + keyCode - KeyEvent.VK_0);
165             return (int)c;
166           }
167         }
168       }
169     }
170     return -1;
171   }
172 }