From 4a70b0879f98f4cbf17933dbe61470adab0e06e2 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Thu, 11 Aug 2016 11:04:34 +0300 Subject: [PATCH] made variables toolbar customizable --- .../src/messages/ActionsBundle.properties | 4 + .../src/messages/XDebuggerBundle.properties | 1 - .../src/idea/LangActions.xml | 12 +++ .../xdebugger/impl/frame/XWatchesView.java | 3 +- .../impl/frame/XWatchesViewImpl.java | 101 +++++------------- .../impl/frame/actions/XMoveWatchDown.java | 56 ++++++++++ .../impl/frame/actions/XMoveWatchUp.java | 56 ++++++++++ .../frame/actions/XRemoveWatchAction.java | 9 +- .../actions/XSwitchWatchesInVariables.java | 39 +++++++ .../impl/ui/DebuggerSessionTabBase.java | 2 +- ...bugTabCustomizableActionGroupProvider.java | 3 +- 11 files changed, 209 insertions(+), 77 deletions(-) create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchDown.java create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchUp.java create mode 100644 platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XSwitchWatchesInVariables.java diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 57356e1e7612..1351b80e42e8 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1027,6 +1027,10 @@ action.XDebugger.RemoveWatch.text=Remove Watch action.XDebugger.RemoveAllWatches.text=Remove All Watches action.XDebugger.NewWatch.text=New Watch... action.XDebugger.EditWatch.text=Edit... +action.XDebugger.CopyWatch.text=Duplicate Watch +action.XDebugger.MoveWatchUp.text=Move Watch Up +action.XDebugger.MoveWatchDown.text=Move Watch Down +action.XDebugger.SwitchWatchesInVariables.text=Show watches in variables tab action.XDebugger.AutoTooltip.text=Value auto tooltip action.XDebugger.AutoTooltip.description=Toggles if value tooltip is shown automatically on mouse over action.XDebugger.Inline.text=Show Values Inline diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index cfff4041837e..07f256cdff9c 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -111,7 +111,6 @@ stack.frame.loading.text=Loading\u2026 invalid.frame= xdebugger.drag.text.0.elements={0} elements xdebugger.drop.text.add.to.watches=Add to watches -debugger.session.tab.show.watches.in.variables=Show watches in variables tab debugger.frames.not.available=Frames are not available debugger.threads.not.available=Threads are not available diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 7a0725c44749..3b2749ae4c2e 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -738,6 +738,14 @@ text="Duplicate Watch" use-shortcut-of="EditorDuplicate"/> + + + + + + + @@ -817,6 +825,10 @@ + + + + diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java index c061b8b39fe1..b024434dd150 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.openapi.actionSystem.DataKey; import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode; import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; import org.jetbrains.annotations.NotNull; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java index a63504cd92db..a8199c5beff4 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java @@ -15,7 +15,6 @@ */ package com.intellij.xdebugger.impl.frame; -import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.dnd.DnDEvent; import com.intellij.ide.dnd.DnDManager; @@ -23,11 +22,14 @@ import com.intellij.ide.dnd.DnDNativeTarget; import com.intellij.openapi.CompositeDisposable; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl; import com.intellij.openapi.ide.CopyPasteManager; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.EmptyRunnable; -import com.intellij.openapi.util.SystemInfo; -import com.intellij.ui.*; +import com.intellij.ui.CaptionPanel; +import com.intellij.ui.ClickListener; +import com.intellij.ui.DoubleClickListener; +import com.intellij.ui.ListenerUtil; import com.intellij.ui.border.CustomLineBorder; import com.intellij.util.Alarm; import com.intellij.util.containers.ContainerUtil; @@ -40,7 +42,7 @@ import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; -import com.intellij.xdebugger.impl.frame.actions.XWatchesTreeActionBase; +import com.intellij.xdebugger.impl.ui.DebuggerSessionTabBase; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebugSessionData; import com.intellij.xdebugger.impl.ui.XDebugSessionTab; @@ -57,7 +59,10 @@ import javax.swing.event.TreeSelectionListener; import javax.swing.tree.TreePath; import java.awt.*; import java.awt.datatransfer.DataFlavor; -import java.awt.event.*; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -75,8 +80,6 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget, super(session); myWatchesInVariables = watchesInVariables; - ActionManager actionManager = ActionManager.getInstance(); - XDebuggerTree tree = getTree(); createNewRootNode(null); @@ -101,74 +104,18 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget, } }.registerCustomShortcutSet(CommonShortcuts.getPaste(), tree, myDisposables); - ToolbarDecorator decorator = ToolbarDecorator.createDecorator(getTree()); + ActionToolbarImpl toolbar = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar( + ActionPlaces.DEBUGGER_TOOLBAR, + DebuggerSessionTabBase.getCustomizedActionGroup(XDebuggerActions.WATCHES_TREE_TOOLBAR_GROUP), + !myWatchesInVariables); + toolbar.setBorder(new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, + myWatchesInVariables ? 0 : 1, + myWatchesInVariables ? 1 : 0)); - decorator.setAddAction(button -> executeAction(XDebuggerActions.XNEW_WATCH)); - decorator.setAddIcon(AllIcons.Debugger.NewWatch); - decorator.setAddActionName(actionManager.getAction(XDebuggerActions.XNEW_WATCH).getTemplatePresentation().getText()); - - AnAction removeWatchAction = actionManager.getAction(XDebuggerActions.XREMOVE_WATCH); - decorator.setRemoveAction(button -> executeAction(XDebuggerActions.XREMOVE_WATCH)); - decorator.setRemoveActionName(removeWatchAction.getTemplatePresentation().getText()); - - decorator.setRemoveActionUpdater(e -> { - removeWatchAction.update(e); - return e.getPresentation().isEnabled(); - }); - decorator.addExtraAction(AnActionButton.fromAction(actionManager.getAction(XDebuggerActions.XCOPY_WATCH))); - decorator.addExtraAction( - new ToggleActionButton(XDebuggerBundle.message("debugger.session.tab.show.watches.in.variables"), AllIcons.Debugger.Watches) { - @Override - public boolean isSelected(AnActionEvent e) { - XDebugSessionTab tab = session.getSessionTab(); - return tab == null || tab.isWatchesInVariables(); - } - - @Override - public void setSelected(AnActionEvent e, boolean state) { - XDebugSessionTab tab = session.getSessionTab(); - if (tab != null) { - tab.setWatchesInVariables(!tab.isWatchesInVariables()); - } - } - }); - decorator.setMoveUpAction(button -> { - List nodes = XWatchesTreeActionBase.getSelectedNodes(getTree(), WatchNode.class); - assert nodes.size() == 1; - myRootNode.moveUp(nodes.get(0)); - updateSessionData(); - }); - decorator.setMoveUpActionUpdater(e -> { - List nodes = XWatchesTreeActionBase.getSelectedNodes(getTree(), WatchNode.class); - if (nodes.size() != 1) return false; - return myRootNode.getIndex(nodes.get(0)) > 0; - }); - decorator.setMoveUpActionName("Move Watch Up"); - decorator.setMoveDownAction(button -> { - List nodes = XWatchesTreeActionBase.getSelectedNodes(getTree(), WatchNode.class); - assert nodes.size() == 1; - myRootNode.moveDown(nodes.get(0)); - updateSessionData(); - }); - decorator.setMoveDownActionUpdater(e -> { - List nodes = XWatchesTreeActionBase.getSelectedNodes(getTree(), WatchNode.class); - if (nodes.size() != 1) return false; - return myRootNode.getIndex(nodes.get(0)) < myRootNode.getWatchChildren().size() - 1; - }); - decorator.setMoveDownActionName("Move Watch Down"); - CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, - SystemInfo.isMac ? 1 : 0, 0, - SystemInfo.isMac ? 0 : 1, 0); - decorator.setToolbarBorder(border); - decorator.setPanelBorder(BorderFactory.createEmptyBorder()); - getPanel().removeAll(); - if (myWatchesInVariables) { - decorator.setToolbarPosition(ActionToolbarPosition.LEFT); - } - else { + if (!myWatchesInVariables) { getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.watches")); } - getPanel().add(decorator.createPanel()); + getPanel().add(toolbar.getComponent(), myWatchesInVariables ? BorderLayout.WEST : BorderLayout.NORTH); installEditListeners(); } @@ -362,6 +309,16 @@ public class XWatchesViewImpl extends XVariablesView implements DnDNativeTarget, updateSessionData(); } + public void moveWatchUp(WatchNode node) { + myRootNode.moveUp(node); + updateSessionData(); + } + + public void moveWatchDown(WatchNode node) { + myRootNode.moveDown(node); + updateSessionData(); + } + public void updateSessionData() { List watchExpressions = ContainerUtil.newArrayList(); List children = myRootNode.getWatchChildren(); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchDown.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchDown.java new file mode 100644 index 000000000000..f1d91c9721ff --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchDown.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.frame.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.ui.CommonActionsPanel; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.xdebugger.impl.frame.XWatchesView; +import com.intellij.xdebugger.impl.frame.XWatchesViewImpl; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNodeImpl; +import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode; +import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author egor + */ +public class XMoveWatchDown extends XWatchesTreeActionBase { + public XMoveWatchDown() { + getTemplatePresentation().setIcon(CommonActionsPanel.Buttons.DOWN.getIcon()); + } + + protected boolean isEnabled(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree) { + List nodes = getSelectedNodes(tree, WatchNodeImpl.class); + if (nodes.size() == 1) { + XDebuggerTreeNode root = tree.getRoot(); + if (root instanceof WatchesRootNode) { + return root.getIndex(nodes.get(0)) < ((WatchesRootNode)root).getWatchChildren().size() - 1; + } + } + return false; + } + + @Override + protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) { + if (watchesView instanceof XWatchesViewImpl) { + ((XWatchesViewImpl)watchesView).moveWatchDown(ContainerUtil.getFirstItem(getSelectedNodes(tree, WatchNodeImpl.class))); + } + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchUp.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchUp.java new file mode 100644 index 000000000000..f465098c4c73 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XMoveWatchUp.java @@ -0,0 +1,56 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.frame.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.ui.CommonActionsPanel; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.xdebugger.impl.frame.XWatchesView; +import com.intellij.xdebugger.impl.frame.XWatchesViewImpl; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNodeImpl; +import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode; +import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author egor + */ +public class XMoveWatchUp extends XWatchesTreeActionBase { + public XMoveWatchUp() { + getTemplatePresentation().setIcon(CommonActionsPanel.Buttons.UP.getIcon()); + } + + protected boolean isEnabled(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree) { + List nodes = getSelectedNodes(tree, WatchNodeImpl.class); + if (nodes.size() == 1) { + XDebuggerTreeNode root = tree.getRoot(); + if (root instanceof WatchesRootNode) { + return root.getIndex(nodes.get(0)) > 0; + } + } + return false; + } + + @Override + protected void perform(@NotNull AnActionEvent e, @NotNull XDebuggerTree tree, @NotNull XWatchesView watchesView) { + if (watchesView instanceof XWatchesViewImpl) { + ((XWatchesViewImpl)watchesView).moveWatchUp(ContainerUtil.getFirstItem(getSelectedNodes(tree, WatchNodeImpl.class))); + } + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XRemoveWatchAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XRemoveWatchAction.java index c34fe36ab0d2..e2648a2835f8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XRemoveWatchAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XRemoveWatchAction.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger.impl.frame.actions; +import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.xdebugger.impl.frame.XWatchesView; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; @@ -30,7 +31,13 @@ public class XRemoveWatchAction extends XWatchesTreeActionBase { @Override public void update(AnActionEvent e) { XDebuggerTree tree = XDebuggerTree.getTree(e); - e.getPresentation().setEnabledAndVisible(tree != null && !getSelectedNodes(tree, WatchNodeImpl.class).isEmpty()); + boolean enabled = tree != null && !getSelectedNodes(tree, WatchNodeImpl.class).isEmpty(); + if (ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) { + e.getPresentation().setEnabled(enabled); + } + else { + e.getPresentation().setEnabledAndVisible(enabled); + } } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XSwitchWatchesInVariables.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XSwitchWatchesInVariables.java new file mode 100644 index 000000000000..3ea71554b867 --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/actions/XSwitchWatchesInVariables.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.xdebugger.impl.frame.actions; + +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.xdebugger.impl.ui.XDebugSessionTab; + +/** + * @author egor + */ +public class XSwitchWatchesInVariables extends ToggleAction { + @Override + public boolean isSelected(AnActionEvent e) { + XDebugSessionTab tab = e.getData(XDebugSessionTab.TAB_KEY); + return tab == null || tab.isWatchesInVariables(); + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + XDebugSessionTab tab = e.getData(XDebugSessionTab.TAB_KEY); + if (tab != null) { + tab.setWatchesInVariables(!tab.isWatchesInVariables()); + } + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java index 172ff0eb20c9..3fe7b233c63b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java @@ -56,7 +56,7 @@ public abstract class DebuggerSessionTabBase extends RunTab { .initFocusContent(DebuggerContentInfo.CONSOLE_CONTENT, LayoutViewOptions.STARTUP, new LayoutAttractionPolicy.FocusOnce(false)); } - protected static ActionGroup getCustomizedActionGroup(final String id) { + public static ActionGroup getCustomizedActionGroup(final String id) { return (ActionGroup)CustomActionsSchema.getInstance().getCorrectedAction(id); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugTabCustomizableActionGroupProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugTabCustomizableActionGroupProvider.java index e0839f75621e..71d7744e639c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugTabCustomizableActionGroupProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugTabCustomizableActionGroupProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2016 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,5 +26,6 @@ public class XDebugTabCustomizableActionGroupProvider extends CustomizableAction public void registerGroups(CustomizableActionGroupRegistrar registrar) { registrar.addCustomizableActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP, "Debug Tool Window Top Toolbar"); registrar.addCustomizableActionGroup(XDebuggerActions.TOOL_WINDOW_LEFT_TOOLBAR_GROUP, "Debug Tool Window Left Toolbar"); + registrar.addCustomizableActionGroup(XDebuggerActions.WATCHES_TREE_TOOLBAR_GROUP, "Debug Watches Toolbar"); } }