diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index a1ff4871eb68..e183ea936d99 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -2914,6 +2914,7 @@ action.TopStripeUnPinButton.text=Unpin
group.Documentation.Navigation.text=Quick Documentation Navigation
action.AddBreakpoint.text=Add Breakpoint
action.AddConditionalBreakpoint.text=Add Conditional Breakpoint\u2026
+action.AddLoggingBreakpoint.text=Add Logging Breakpoint\u2026
group.XDebugger.Attach.Dialog.Settings.text=Attach dialog settings
action.XDebugger.Show.Breakpoints.Over.Line.Numbers.text=Breakpoints Over Line Numbers
diff --git a/platform/xdebugger-impl/resources/META-INF/xdebugger.xml b/platform/xdebugger-impl/resources/META-INF/xdebugger.xml
index f7020e586eda..70429ff2d8cf 100644
--- a/platform/xdebugger-impl/resources/META-INF/xdebugger.xml
+++ b/platform/xdebugger-impl/resources/META-INF/xdebugger.xml
@@ -231,6 +231,7 @@
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java
index ecb078585fce..3d0285c46206 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/AddLineBreakpointAction.java
@@ -16,9 +16,12 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.ExperimentalUI;
import com.intellij.util.ModalityUiUtil;
import com.intellij.xdebugger.XSourcePosition;
+import com.intellij.xdebugger.breakpoints.SuspendPolicy;
import com.intellij.xdebugger.impl.XDebuggerManagerImpl;
import com.intellij.xdebugger.impl.XSourcePositionImpl;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil;
+import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
+import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointProxy;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@@ -39,9 +42,10 @@ public class AddLineBreakpointAction extends DumbAwareAction implements ActionRe
if (editor == null) return;
XSourcePosition position = getLineBreakpointPosition(e);
assert position != null;
+ String selection = editor.getSelectionModel().getSelectedText();
XBreakpointUtil.toggleLineBreakpointProxy(project, position, false, editor, false, false, true)
.thenAccept(bp -> {
- if (bp != null && isConditional()) {
+ if (bp != null && editBreakpointSettings(bp, selection)) {
ModalityUiUtil.invokeLaterIfNeeded(ModalityState.defaultModalityState(), () -> {
EditorGutterComponentEx gutter = (EditorGutterComponentEx)editor.getGutter();
int x = -gutter.getWidth() + gutter.getLineNumberAreaOffset() + gutter.getLineNumberAreaWidth() / 2;
@@ -82,13 +86,34 @@ public class AddLineBreakpointAction extends DumbAwareAction implements ActionRe
return null;
}
- protected boolean isConditional() {
+ /**
+ * Tweak breakpoint settings after its creation.
+ * @return true, if a breakpoint editor UI should be shown
+ */
+ @ApiStatus.OverrideOnly
+ protected boolean editBreakpointSettings(XLineBreakpointProxy bp, @Nullable String editorSelection) {
return false;
}
public static class WithCondition extends AddLineBreakpointAction implements ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
@Override
- protected boolean isConditional() {
+ protected boolean editBreakpointSettings(XLineBreakpointProxy bp, @Nullable String editorSelection) {
+ bp.setConditionEnabled(true);
+ bp.setConditionExpression(XExpressionImpl.fromText(editorSelection));
+ return true;
+ }
+ }
+
+ public static class WithLogging extends AddLineBreakpointAction implements ActionRemoteBehaviorSpecification.FrontendOtherwiseBackend {
+ @Override
+ protected boolean editBreakpointSettings(XLineBreakpointProxy bp, @Nullable String editorSelection) {
+ bp.setSuspendPolicy(SuspendPolicy.NONE);
+ if (editorSelection != null) {
+ bp.setLogExpressionObject(XExpressionImpl.fromText(editorSelection));
+ }
+ else {
+ bp.setLogMessage(true);
+ }
return true;
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.form
index cb1f3e2d478c..3729b945b3ae 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.form
@@ -27,15 +27,14 @@
-
+
-
+
-
-
-
-
-
+
+
+
+
@@ -77,7 +76,7 @@
-
+
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
index 6cc5704c457d..36d86d6903f0 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
@@ -2,8 +2,10 @@
package com.intellij.xdebugger.impl.breakpoints.ui;
import com.intellij.openapi.project.Project;
+import com.intellij.ui.components.JBCheckBox;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
+import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
@@ -25,8 +27,10 @@ import java.awt.event.ActionListener;
public class XBreakpointActionsPanel extends XBreakpointPropertiesSubPanel {
public static final String LOG_EXPRESSION_HISTORY_ID = "breakpointLogExpression";
+ private JLabel myLogMessageLabel;
private JCheckBox myLogMessageCheckBox;
private JCheckBox myLogExpressionCheckBox;
+ private JPanel myLogExpressionCheckBoxPanel;
private JPanel myLogExpressionPanel;
private JPanel myContentPane;
private JPanel myMainPanel;
@@ -36,8 +40,14 @@ public class XBreakpointActionsPanel extends XBreakpointPropertiesSubPanel {
private JCheckBox myLogStack;
private @Nullable XDebuggerExpressionComboBox myLogExpressionComboBox;
- public void init(Project project, @NotNull XBreakpointProxy breakpoint, @Nullable XDebuggerEditorsProvider debuggerEditorsProvider) {
+ private boolean myShowAllOptions;
+
+ public void init(Project project,
+ @NotNull XBreakpointProxy breakpoint,
+ @Nullable XDebuggerEditorsProvider debuggerEditorsProvider,
+ boolean showAllOptions) {
init(project, breakpoint);
+ myShowAllOptions = showAllOptions;
if (debuggerEditorsProvider != null) {
ActionListener listener = new ActionListener() {
@Override
@@ -45,6 +55,7 @@ public class XBreakpointActionsPanel extends XBreakpointPropertiesSubPanel {
onCheckboxChanged();
}
};
+ myLogExpressionCheckBox = new JBCheckBox(XDebuggerBundle.message("xbreakpoints.log.expression.checkbox"));
myLogExpressionComboBox = new XDebuggerExpressionComboBox(project, debuggerEditorsProvider, LOG_EXPRESSION_HISTORY_ID,
null, true, false);
myLanguageChooserPanel.add(myLogExpressionComboBox.getLanguageChooser(), BorderLayout.CENTER);
@@ -100,7 +111,20 @@ public class XBreakpointActionsPanel extends XBreakpointPropertiesSubPanel {
if (myLogExpressionComboBox != null) {
XExpression logExpression = myBreakpoint.getLogExpressionObjectInt();
myLogExpressionComboBox.setExpression(logExpression);
- myLogExpressionCheckBox.setSelected(myBreakpoint.isLogExpressionEnabled() && logExpression != null);
+ boolean hideCheckbox = !myShowAllOptions && logExpression == null;
+ myLogExpressionCheckBox.setSelected(hideCheckbox || (myBreakpoint.isLogExpressionEnabled() && logExpression != null));
+ myLogExpressionCheckBoxPanel.removeAll();
+ if (hideCheckbox) {
+ var label = new JLabel(XDebuggerBundle.message("xbreakpoints.log.expression.checkbox"));
+ label.setBorder(JBUI.Borders.empty(0, 4, 4, 0));
+ label.setLabelFor(myLogExpressionComboBox.getComboBox());
+ myLogExpressionCheckBoxPanel.add(label);
+ myLogExpressionPanel.setBorder(JBUI.Borders.emptyLeft(3));
+ myLogMessageLabel.setBorder(JBUI.Borders.empty(0, 4, 4, 0)); // to unify with other labels
+ } else {
+ myLogExpressionCheckBoxPanel.add(myLogExpressionCheckBox);
+ myLogExpressionPanel.setBorder(JBUI.Borders.emptyLeft(UIUtil.getCheckBoxTextHorizontalOffset(myLogExpressionCheckBox)));
+ }
}
onCheckboxChanged();
}
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 e814460f84f3..24e39c26684a 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
@@ -19,10 +19,7 @@ import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
-import com.intellij.xdebugger.breakpoints.XBreakpointManager;
-import com.intellij.xdebugger.breakpoints.XBreakpointType;
-import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
-import com.intellij.xdebugger.breakpoints.XLineBreakpointType;
+import com.intellij.xdebugger.breakpoints.*;
import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
@@ -152,7 +149,7 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele
XDebuggerEditorsProvider debuggerEditorsProvider = breakpoint.getEditorsProvider();
if (breakpointType.getVisibleStandardPanels().contains(XBreakpointType.StandardPanels.ACTIONS)) {
- myActionsPanel.init(project, breakpoint, debuggerEditorsProvider);
+ myActionsPanel.init(project, breakpoint, debuggerEditorsProvider, myShowAllOptions);
mySubPanels.add(myActionsPanel);
}
else {
@@ -229,12 +226,17 @@ public class XLightBreakpointPropertiesPanel implements XSuspendPolicyPanel.Dele
@Override
public void focusGained(FocusEvent event) {
JComponent compToFocus = null;
- if (myConditionComboBox != null && myConditionComboBox.getComboBox().isEnabled()) {
- compToFocus = myConditionComboBox.getEditorComponent();
- }
- else if (breakpointType.getVisibleStandardPanels().contains(XBreakpointType.StandardPanels.ACTIONS)) {
+ var actionsAvailable = breakpointType.getVisibleStandardPanels().contains(XBreakpointType.StandardPanels.ACTIONS);
+ var conditionEditable = myConditionComboBox != null && myConditionComboBox.getComboBox().isEnabled();
+ var isSuspending = breakpoint.getSuspendPolicy() != SuspendPolicy.NONE;
+ if (actionsAvailable && (!isSuspending || !conditionEditable)) {
+ // Focus actions panel in case of non-suspending breakpoint (or if condition is explicitly disabled).
+ // This is important for the "Add Logging Breakpoint" action which should focus on the logging expression.
compToFocus = myActionsPanel.getDefaultFocusComponent();
}
+ else if (conditionEditable) {
+ compToFocus = myConditionComboBox.getEditorComponent();
+ }
if (compToFocus != null) {
IdeFocusManager.findInstance().requestFocus(compToFocus, false);
}