From db78bf179b7190809861fe7c9053ece7f2c0b800 Mon Sep 17 00:00:00 2001 From: andrey zaytsev Date: Mon, 20 Jun 2011 15:13:41 +0400 Subject: [PATCH] xbreakpoints-ui. npe fixed. Actions in gutter popup-menu rearranged. hide on key outside. show more options when suspend checkbox is off. --- .../impl/EditorGutterComponentImpl.java | 2 +- .../src/messages/XDebuggerBundle.properties | 2 + .../impl/actions/EditBreakpointAction.java | 6 ++- .../impl/breakpoints/XBreakpointBase.java | 8 ++- .../ui/XLightBreakpointPropertiesPanel.java | 24 ++++++--- .../breakpoints/ui/XSuspendPolicyPanel.java | 33 +++++++++++- .../xdebugger/impl/ui/DebuggerUIUtil.java | 54 +++++++++++++++---- 7 files changed, 108 insertions(+), 21 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java index 90bedf032547..6ef01eb50412 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorGutterComponentImpl.java @@ -1277,7 +1277,7 @@ class EditorGutterComponentImpl extends EditorGutterComponentEx implements Mouse public Point getPoint(GutterIconRenderer renderer) { for (int line : myLineToGutterRenderers.keys()) { for (GutterIconRenderer gutterIconRenderer : myLineToGutterRenderers.get(line)) { - if (gutterIconRenderer == renderer) { + if (gutterIconRenderer.equals(renderer)) { int x = getLineMarkerAreaOffset() + 1; final int y = myEditor.logicalPositionToXY(new LogicalPosition(line, 0)).y; return new Point(x, y); diff --git a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties index 3d8a4ddef3a1..ead0678e90a6 100644 --- a/platform/platform-resources-en/src/messages/XDebuggerBundle.properties +++ b/platform/platform-resources-en/src/messages/XDebuggerBundle.properties @@ -9,6 +9,8 @@ xdebugger.remove.line.breakpoint.action.text=Remove xdebugger.disable.breakpoint.action.text=Disable xdebugger.enable.breakpoint.action.text=Enable xdebugger.view.breakpoint.properties.action=Properties +xdebugger.view.breakpoint.reveal.action=Show Breakpoints Dialog +xdebugger.view.breakpoint.edit.action=Edit xbreakpoint.tooltip.suspend.policy.thread=Suspend: thread xbreakpoint.tooltip.suspend.policy.none=Suspend: none diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointAction.java index 08927c8ea9c8..a57e2014ab42 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/EditBreakpointAction.java @@ -53,8 +53,10 @@ public class EditBreakpointAction extends AnAction { if (editor != null) { final EditorGutterComponentEx gutterComponent = ((EditorEx)editor).getGutterComponentEx(); Point point = gutterComponent.getPoint(myBreakpointGutterRenderer); - final Icon icon = myBreakpointGutterRenderer.getIcon(); - DebuggerUIUtil.showBreakpointEditorBalloon(project, new Point(point.x + icon.getIconWidth()/2 + gutterComponent.getIconsAreaWidth(), point.y + icon.getIconHeight()/2), gutterComponent, false, myBreakpoint); + if (point != null) { + final Icon icon = myBreakpointGutterRenderer.getIcon(); + DebuggerUIUtil.showBreakpointEditorBalloon(project, new Point(point.x + icon.getIconWidth()/2 + gutterComponent.getIconsAreaWidth(), point.y + icon.getIconHeight()/2), gutterComponent, false, myBreakpoint); + } } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java index b16495f1e779..15d332b4a3df 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java @@ -39,6 +39,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointType; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.actions.EditBreakpointAction; +import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction; import com.intellij.xdebugger.ui.DebuggerIcons; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -360,6 +361,11 @@ public class XBreakpointBase, P extends XBreakpointP public ActionGroup getPopupMenuActions() { DefaultActionGroup group = new DefaultActionGroup(); final XDebuggerManager debuggerManager = XDebuggerManager.getInstance(getProject()); + + group.add(new EditBreakpointAction(XDebuggerBundle.message("xdebugger.view.breakpoint.edit.action"), XBreakpointBase.this, this)); + + group.add(new Separator()); + if (!debuggerManager.getBreakpointManager().isDefaultBreakpoint(XBreakpointBase.this)) { group.add(new RemoveBreakpointGutterIconAction(XBreakpointBase.this)); } @@ -369,7 +375,7 @@ public class XBreakpointBase, P extends XBreakpointP } group.add(new Separator()); - group.add(new EditBreakpointAction(XDebuggerBundle.message("xdebugger.view.breakpoint.properties.action"), XBreakpointBase.this, this)); + group.add(new ViewBreakpointsAction(XDebuggerBundle.message("xdebugger.view.breakpoint.reveal.action"), XBreakpointBase.this)); return group; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java index 2520625f82fb..e12a835764a0 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java @@ -40,9 +40,10 @@ import java.util.List; * Time: 15:46 * To change this template use File | Settings | File Templates. */ -public class XLightBreakpointPropertiesPanel> { +public class XLightBreakpointPropertiesPanel> implements XSuspendPolicyPanel.Delegate { private LinkLabel myShowMoreOptionsLink; + private boolean myShowMoreOptions; private void createUIComponents() { myShowMoreOptionsLink = new LinkLabel("More Options", null, new LinkListener() { @@ -55,6 +56,15 @@ public class XLightBreakpointPropertiesPanel> { }); } + @Override + public void showMoreOptionsIfNeeded() { + if (myShowMoreOptions) { + if (myDelegate != null) { + myDelegate.showMoreOptions(); + } + } + } + public interface Delegate { void showMoreOptions(); } @@ -90,6 +100,8 @@ public class XLightBreakpointPropertiesPanel> { XBreakpointType breakpointType = XBreakpointUtil.getType(breakpoint); mySuspendPolicyPanel.init(project, breakpointManager, breakpoint); + mySuspendPolicyPanel.setDelegate(this); + mySubPanels.add(mySuspendPolicyPanel); myMasterBreakpointPanel.init(project, breakpointManager, breakpoint); mySubPanels.add(myMasterBreakpointPanel); @@ -106,14 +118,14 @@ public class XLightBreakpointPropertiesPanel> { myConditionPanel.setVisible(false); } - boolean showMoreOptions = false; + myShowMoreOptions = false; for (XBreakpointPropertiesSubPanel panel : mySubPanels) { if (panel.lightVariant(showAllOptions)) { - showMoreOptions = true; + myShowMoreOptions = true; } } - myShowMoreOptionsLink.setVisible(showMoreOptions); + myShowMoreOptionsLink.setVisible(myShowMoreOptions); myCustomPanels = new ArrayList>(); XBreakpointCustomPropertiesPanel customPropertiesPanel = breakpointType.createCustomPropertiesPanel(); @@ -121,8 +133,6 @@ public class XLightBreakpointPropertiesPanel> { myCustomPropertiesPanelWrapper.add(customPropertiesPanel.getComponent(), BorderLayout.CENTER); myCustomPanels.add(customPropertiesPanel); } - - loadProperties(); } public void saveProperties() { @@ -145,7 +155,7 @@ public class XLightBreakpointPropertiesPanel> { } } - private void loadProperties() { + public void loadProperties() { for (XBreakpointPropertiesSubPanel panel : mySubPanels) { panel.loadProperties(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java index 526dd3fb1901..a7bf08790110 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XSuspendPolicyPanel.java @@ -24,6 +24,8 @@ import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.util.HashMap; import java.util.Map; @@ -44,6 +46,12 @@ public class XSuspendPolicyPanel> extends XBreakpointPr private JPanel myContentPane; private Map mySuspendRadioButtons; + public interface Delegate { + void showMoreOptionsIfNeeded(); + } + + private Delegate myDelegate; + public void init(Project project, final XBreakpointManager breakpointManager, @NotNull B breakpoint) { super.init(project, breakpointManager, breakpoint); mySuspendRadioButtons = new HashMap(); @@ -52,6 +60,15 @@ public class XSuspendPolicyPanel> extends XBreakpointPr mySuspendRadioButtons.put(SuspendPolicy.NONE, mySuspendNoneRadioButton); @NonNls String card = myBreakpointType.isSuspendThreadSupported() ? "radioButtons" : "checkbox"; ((CardLayout)mySuspendPolicyPanel.getLayout()).show(mySuspendPolicyPanel, card); + + mySuspendCheckBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + if (myDelegate != null && !mySuspendCheckBox.isSelected()) { + myDelegate.showMoreOptionsIfNeeded(); + } + } + }); } @Override @@ -64,7 +81,13 @@ public class XSuspendPolicyPanel> extends XBreakpointPr void loadProperties() { SuspendPolicy suspendPolicy = myBreakpoint.getSuspendPolicy(); mySuspendRadioButtons.get(suspendPolicy).setSelected(true); - mySuspendCheckBox.setSelected(suspendPolicy != SuspendPolicy.NONE); + final boolean selected = suspendPolicy != SuspendPolicy.NONE; + mySuspendCheckBox.setSelected(selected); + if (!selected) { + if (myDelegate != null) { + myDelegate.showMoreOptionsIfNeeded(); + } + } } private SuspendPolicy getConfiguredSuspendPolicy() { @@ -85,4 +108,12 @@ public class XSuspendPolicyPanel> extends XBreakpointPr void saveProperties() { myBreakpoint.setSuspendPolicy(getConfiguredSuspendPolicy()); } + + public Delegate getDelegate() { + return myDelegate; + } + + public void setDelegate(Delegate delegate) { + myDelegate = delegate; + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java index 0cdf85fb4ab8..829d94406c5f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerUIUtil.java @@ -23,11 +23,14 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.DimensionService; +import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.WindowManager; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.awt.RelativePoint; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointListener; +import com.intellij.xdebugger.breakpoints.XBreakpointManager; import com.intellij.xdebugger.frame.XFullValueEvaluator; import com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel; import org.jetbrains.annotations.NonNls; @@ -136,22 +139,45 @@ public class DebuggerUIUtil { } public static void showBreakpointEditorBalloon(final Project project, - @Nullable final Point point, final JComponent gutterComponent, + @Nullable final Point point, final JComponent component, final boolean showAllOptions, final XBreakpoint breakpoint) { + final XBreakpointManager breakpointManager = XDebuggerManager.getInstance(project).getBreakpointManager(); final XLightBreakpointPropertiesPanel propertiesPanel = - new XLightBreakpointPropertiesPanel(project, XDebuggerManager.getInstance(project).getBreakpointManager(), + new XLightBreakpointPropertiesPanel(project, breakpointManager, breakpoint, showAllOptions); - final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(propertiesPanel.getMainPanel()). + final JComponent mainPanel = propertiesPanel.getMainPanel(); + final Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(mainPanel). setHideOnAction(false). - setHideOnClickOutside(false). + setHideOnClickOutside(true). setHideOnKeyOutside(false). setCloseButtonEnabled(true). setDialogMode(true). - setFillColor(propertiesPanel.getMainPanel().getBackground()). + setFillColor(mainPanel.getBackground()). setTitle(breakpoint.getType().getDisplayText(breakpoint)). - setHideOnFrameResize(false).createBalloon(); + setHideOnFrameResize(false). + setAnimationCycle(200).createBalloon(); + final XBreakpointListener> breakpointListener = new XBreakpointListener>() { + @Override + public void breakpointAdded(@NotNull XBreakpoint breakpoint1) { + } + + @Override + public void breakpointRemoved(@NotNull XBreakpoint breakpoint1) { + if (breakpoint1.equals(breakpoint)) { + balloon.hide(); + } + } + + @Override + public void breakpointChanged(@NotNull XBreakpoint breakpoint1) { + if (breakpoint1.equals(breakpoint)) { + balloon.hide(); + } + } + }; + breakpointManager.addBreakpointListener(breakpointListener); balloon.addListener(new JBPopupListener() { @Override public void beforeShown(LightweightWindowEvent event) { @@ -160,21 +186,31 @@ public class DebuggerUIUtil { @Override public void onClosed(LightweightWindowEvent event) { propertiesPanel.saveProperties(); + breakpointManager.removeBreakpointListener(breakpointListener); } }); + propertiesPanel.setDelegate(new XLightBreakpointPropertiesPanel.Delegate() { @Override public void showMoreOptions() { balloon.hide(); - showBreakpointEditorBalloon(project, point, gutterComponent, true, breakpoint); + showBreakpointEditorBalloon(project, point, component, true, breakpoint); } }); + propertiesPanel.loadProperties(); + if (point == null) { - balloon.showInCenterOf(gutterComponent); + balloon.showInCenterOf(component); } else { - balloon.show(new RelativePoint(gutterComponent, point), Balloon.Position.atRight); + balloon.show(new RelativePoint(component, point), Balloon.Position.atRight); } + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + IdeFocusManager.findInstance().requestFocus(mainPanel, true); + } + }); } private static class FullValueEvaluationCallbackImpl implements XFullValueEvaluator.XFullValueEvaluationCallback {