diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java
index 77b8d228b939..bc2a1a499736 100644
--- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java
+++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBase.java
@@ -46,7 +46,9 @@ import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
/**
* @author yole
@@ -98,16 +100,9 @@ public abstract class HierarchyBrowserBase extends SimpleToolWindowPanel impleme
protected void appendActions(@NotNull DefaultActionGroup actionGroup, @Nullable String helpID) {
actionGroup.add(myAutoScrollToSourceHandler.createToggleAction());
- final ActionManager actionManager = ActionManager.getInstance();
+ ActionManager actionManager = ActionManager.getInstance();
actionGroup.add(actionManager.getAction(IdeActions.ACTION_EXPAND_ALL));
- actionGroup.add(new PinToolwindowTabAction(){
- @Override
- public void update(AnActionEvent event) {
- super.update(event);
- // sometimes there is no content to close, e.g. in usage view preview
- event.getPresentation().setVisible(myContent != null);
- }
- });
+ actionGroup.add(actionManager.getAction(PinToolwindowTabAction.ACTION_NAME));
actionGroup.add(CommonActionsManager.getInstance().createExportToTextFileAction(new ExporterToTextFileHierarchy(this)));
actionGroup.add(new CloseAction());
if (helpID != null) {
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java
index 9a2a5ac41c39..20f7e9f2ec65 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/PinActiveTabAction.java
@@ -18,95 +18,129 @@ package com.intellij.ide.actions;
import com.intellij.execution.ui.layout.ViewContext;
import com.intellij.icons.AllIcons;
import com.intellij.ide.IdeBundle;
-import com.intellij.openapi.actionSystem.ActionPlaces;
-import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.actionSystem.ToggleAction;
+import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.fileEditor.impl.EditorWindow;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindow;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.ContentManagerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+/**
+ * Pins any kind of tab in context: editor tab, toolwindow tab or other tabs.
+ *
+ * todo drop TW and EW, pro: one action-one shortcut; contra: menu|Window changes
+ */
public class PinActiveTabAction extends ToggleAction implements DumbAware {
+ public static abstract class Handler {
+ public final boolean isPinned;
+ public final boolean isActiveTab;
+
+ abstract void setPinned(boolean value);
+
+ public Handler(boolean isPinned, boolean isActiveTab) {
+ this.isPinned = isPinned;
+ this.isActiveTab = isActiveTab;
+ }
+ }
+
@Override
public boolean isSelected(AnActionEvent e) {
- Content content = getNonEditorContent(e);
- if (content != null && content.isPinnable()) return content.isPinned();
-
- EditorWindow window = getEditorWindow(e);
- VirtualFile selectedFile = window == null ? null : getFileInWindow(e, window);
- return selectedFile != null && window.isFilePinned(selectedFile);
+ Handler handler = getHandler(e);
+ return handler != null && handler.isPinned;
}
@Override
public void setSelected(AnActionEvent e, boolean state) {
- Content content = getNonEditorContent(e);
- if (content != null && content.isPinnable()) {
- content.setPinned(state);
- }
- else {
- EditorWindow window = getEditorWindow(e);
- VirtualFile selectedFile = window == null ? null : getFileInWindow(e, window);
- if (selectedFile != null) {
- window.setFilePinned(selectedFile, state);
- }
- }
+ Handler handler = getHandler(e);
+ if (handler != null) handler.setPinned(state);
}
@Override
public void update(@NotNull AnActionEvent e) {
- boolean selected = isSelected(e);
+ Handler handler = getHandler(e);
+ boolean enabled = handler != null;
+ boolean selected = enabled && handler.isPinned;
+
+ e.getPresentation().setIcon(ActionPlaces.isToolbarPlace(e.getPlace()) ? AllIcons.General.Pin_tab : null);
e.getPresentation().putClientProperty(SELECTED_PROPERTY, selected);
String text;
- boolean enable;
- EditorWindow window = getEditorWindow(e);
- VirtualFile selectedFile = window == null ? null : getFileInWindow(e, window);
- if (selectedFile != null) {
- enable = !window.getOwner().isPreview();
- }
- else {
- Content content = getNonEditorContent(e);
- enable = content != null && content.isPinnable();
- }
// add the word "active" if the target tab is not current
- if (ActionPlaces.isMainMenuOrActionSearch(e.getPlace()) ||
- !(selectedFile == null || selectedFile.equals(e.getData(CommonDataKeys.VIRTUAL_FILE)))) {
+ if (ActionPlaces.isMainMenuOrActionSearch(e.getPlace()) || handler != null && !handler.isActiveTab) {
text = selected ? IdeBundle.message("action.unpin.active.tab") : IdeBundle.message("action.pin.active.tab");
}
else {
text = selected ? IdeBundle.message("action.unpin.tab") : IdeBundle.message("action.pin.tab");
}
- e.getPresentation().setIcon(ActionPlaces.isToolbarPlace(e.getPlace())? AllIcons.General.Pin_tab : null);
e.getPresentation().setText(text);
- e.getPresentation().setEnabledAndVisible(enable);
+ e.getPresentation().setEnabledAndVisible(enabled);
+ }
+
+ protected Handler getHandler(@NotNull AnActionEvent e) {
+ Project project = e.getProject();
+ EditorWindow currentWindow = e.getData(EditorWindow.DATA_KEY);
+
+ Content content = currentWindow != null ? null : getContentFromEvent(e);
+ if (content != null && content.isPinnable()) {
+ return new Handler(content.isPinned(), content.getManager().getSelectedContent() == content) {
+ @Override
+ void setPinned(boolean value) {
+ content.setPinned(value);
+ }
+ };
+ }
+
+ final EditorWindow window = currentWindow != null ? currentWindow :
+ project != null ? FileEditorManagerEx.getInstanceEx(project).getCurrentWindow() : null;
+ VirtualFile selectedFile = window == null ? null : getFileFromEvent(e, window);
+ if (selectedFile != null) {
+ return new Handler(window.isFilePinned(selectedFile), selectedFile.equals(e.getData(CommonDataKeys.VIRTUAL_FILE))) {
+ @Override
+ void setPinned(boolean value) {
+ window.setFilePinned(selectedFile, value);
+ }
+ };
+ }
+ return null;
}
@Nullable
- private static Content getNonEditorContent(@NotNull AnActionEvent e) {
- if (e.getData(EditorWindow.DATA_KEY) != null) return null;
+ protected VirtualFile getFileFromEvent(@NotNull AnActionEvent e, @NotNull EditorWindow window) {
+ return getFileInWindow(e, window);
+ }
+
+ @Nullable
+ protected Content getContentFromEvent(@NotNull AnActionEvent e) {
+ Content content = getNonToolWindowContent(e);
+ return content != null ? content : getToolWindowContent(e);
+ }
+
+ @Nullable
+ private static Content getNonToolWindowContent(@NotNull AnActionEvent e) {
+ Content result = null;
Content[] contents = e.getData(ViewContext.CONTENT_KEY);
- if (contents != null && contents.length == 1) return contents[0];
+ if (contents != null && contents.length == 1) result = contents[0];
+ if (result != null && result.isPinnable()) return result;
ContentManager contentManager = ContentManagerUtil.getContentManagerFromContext(e.getDataContext(), true);
- return contentManager == null ? null : contentManager.getSelectedContent();
+ result = contentManager != null? contentManager.getSelectedContent() : null;
+ if (result != null && result.isPinnable()) return result;
+ return getToolWindowContent(e);
}
@Nullable
- private static EditorWindow getEditorWindow(@NotNull AnActionEvent e) {
- EditorWindow window = e.getData(EditorWindow.DATA_KEY);
- if (window == null) {
- Project project = e.getProject();
- window = project == null ? null : FileEditorManagerEx.getInstanceEx(project).getCurrentWindow();
- }
- return window;
+ private static Content getToolWindowContent(@NotNull AnActionEvent e) {
+ // note to future readers: TW tab "pinned" icon is shown when content.getUserData(TW.SHOW_CONTENT_ICON) is true
+ ToolWindow window = PlatformDataKeys.TOOL_WINDOW.getData(e.getDataContext());
+ Content result = window != null ? window.getContentManager().getSelectedContent() : null;
+ return result != null && result.isPinnable() ? result : null;
}
@Nullable
@@ -116,4 +150,25 @@ public class PinActiveTabAction extends ToggleAction implements DumbAware {
if (file != null && window.isFileOpen(file)) return file;
return null;
}
+
+ public static class TW extends PinActiveTabAction {
+ @Nullable
+ @Override
+ protected VirtualFile getFileFromEvent(@NotNull AnActionEvent e, @NotNull EditorWindow window) {
+ return null;
+ }
+
+ @Override
+ protected Content getContentFromEvent(@NotNull AnActionEvent e) {
+ return getToolWindowContent(e);
+ }
+ }
+
+ public static class EW extends PinActiveTabAction {
+
+ @Override
+ protected Content getContentFromEvent(@NotNull AnActionEvent e) {
+ return null;
+ }
+ }
}
diff --git a/platform/platform-impl/src/com/intellij/ui/content/tabs/PinToolwindowTabAction.java b/platform/platform-impl/src/com/intellij/ui/content/tabs/PinToolwindowTabAction.java
index acb2e8ab47ef..b8f3053a7a47 100644
--- a/platform/platform-impl/src/com/intellij/ui/content/tabs/PinToolwindowTabAction.java
+++ b/platform/platform-impl/src/com/intellij/ui/content/tabs/PinToolwindowTabAction.java
@@ -15,70 +15,18 @@
*/
package com.intellij.ui.content.tabs;
-import com.intellij.icons.AllIcons;
-import com.intellij.openapi.actionSystem.*;
-import com.intellij.openapi.project.DumbAware;
-import com.intellij.openapi.wm.ToolWindow;
-import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
-import com.intellij.ui.content.Content;
-import com.intellij.ui.content.ContentManager;
-import com.intellij.ui.content.TabbedPaneContentUI;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import com.intellij.ide.actions.PinActiveTabAction;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
/**
* @author spleaner
*/
-public class PinToolwindowTabAction extends ToggleAction implements DumbAware {
- @NonNls public static final String ACTION_NAME = "PinToolwindowTab";
+public class PinToolwindowTabAction extends PinActiveTabAction.TW {
+ public static final String ACTION_NAME = "PinToolwindowTab";
public static AnAction getPinAction() {
return ActionManager.getInstance().getAction(ACTION_NAME);
}
- public PinToolwindowTabAction() {
- super("Pin Tab", "Pin tool window tab", AllIcons.General.Pin_tab);
- }
-
- @Nullable
- private static Content getContextContent(@NotNull AnActionEvent event) {
- final ToolWindow window = PlatformDataKeys.TOOL_WINDOW.getData(event.getDataContext());
- if (window != null) {
- final ContentManager contentManager = window.getContentManager();
- if (contentManager != null) {
- return contentManager.getSelectedContent();
- }
- }
-
- return null;
- }
-
- @Override
- public boolean isSelected(AnActionEvent event) {
- final Content content = getContextContent(event);
- return content != null && content.isPinned();
- }
-
- @Override
- public void setSelected(AnActionEvent event, boolean flag) {
- final Content content = getContextContent(event);
- if (content != null) content.setPinned(flag);
- }
-
- @Override
- public void update(AnActionEvent event) {
- super.update(event);
- Presentation presentation = event.getPresentation();
- final Content content = getContextContent(event);
- boolean enabled = content != null && content.isPinnable();
-
- if (enabled) {
- presentation.setIcon(
- TabbedPaneContentUI.POPUP_PLACE.equals(event.getPlace()) || ToolWindowContentUi.POPUP_PLACE.equals(event.getPlace()) ? null : AllIcons.General.Pin_tab);
- }
-
- presentation.setEnabled(enabled);
- presentation.setVisible(enabled);
- }
}
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 9c8d817ffc67..8c2d1b504fd2 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -858,6 +858,8 @@ action.HideSideWindows.text=Hide Side Tool Windows
action.HideSideWindows.description=Hide all windows on this side
action.HideAllWindows.text=Hide All _Tool Windows
action.HideAllWindows.description=Hide all tool windows
+action.PinToolwindowTab.text=P_in Active Tool Window Tab
+action.PinToolwindowTab.description=Pin active tool window tab
action.JumpToLastWindow.text=_Jump to Last Tool Window
action.JumpToLastWindow.description=Activate last focused tool window
group.ActiveToolwindowGroup.text=Active Tool Window
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index dcb488175b2c..b0e5595b2748 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -197,8 +197,6 @@
-
-
@@ -389,6 +387,7 @@
+
@@ -411,7 +410,7 @@
-
+