diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java index dd62294432b1..480bb063c103 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/QuickEvaluateAction.java @@ -60,7 +60,7 @@ public class QuickEvaluateAction extends XDebuggerActionBase { @Override public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { - if (!myHandler.isEnabled(project)) { + if (!myHandler.isEnabled(project, event)) { return false; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java index d3768ae3ad72..db829c7c71cf 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java @@ -110,7 +110,8 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler { } expression = new XExpressionImpl(expression.getExpression(), language, expression.getCustomInfo(), expression.getMode()); } - new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, expression, stackFrame == null ? null : stackFrame.getSourcePosition()).show(); + XSourcePosition position = stackFrame == null ? null : stackFrame.getSourcePosition(); + new XDebuggerEvaluationDialog(session, editorsProvider, expression, position, evaluator.isCodeFragmentEvaluationSupported()).show(); } /** diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java index f54c83f0227e..92c1cba1e717 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java @@ -56,7 +56,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent { private final JPanel myMainPanel; public ExpressionInputComponent(final @NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition, - @Nullable XExpression expression, Disposable parentDisposable) { + @Nullable XExpression expression, Disposable parentDisposable, boolean showHelp) { super(XDebuggerBundle.message("xdebugger.dialog.title.evaluate.expression")); myMainPanel = new JPanel(new BorderLayout()); //myMainPanel.add(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.expression")), BorderLayout.WEST); @@ -80,6 +80,8 @@ public class ExpressionInputComponent extends EvaluationInputComponent { help.setComponentStyle(UIUtil.ComponentStyle.SMALL); help.setFontColor(UIUtil.FontColor.BRIGHTER); myMainPanel.add(help, BorderLayout.SOUTH); + help.setVisible(showHelp); + if (expression != null) { myExpressionEditor.setExpression(expression); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java index 84c81498b6f6..fb4000f9d711 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java @@ -52,6 +52,7 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.util.function.Supplier; /** * @author nik @@ -68,6 +69,8 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { private final XDebuggerTreePanel myTreePanel; private EvaluationInputComponent myInputComponent; private final XDebugSession mySession; + private final Supplier myEvaluatorSupplier; + private final Project myProject; private final XDebuggerEditorsProvider myEditorsProvider; private EvaluationMode myMode; private XSourcePosition mySourcePosition; @@ -76,18 +79,40 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { public XDebuggerEvaluationDialog(@NotNull XDebugSession session, @NotNull XDebuggerEditorsProvider editorsProvider, - @NotNull XDebuggerEvaluator evaluator, @NotNull XExpression text, - @Nullable XSourcePosition sourcePosition) { - super(WindowManager.getInstance().getFrame(session.getProject()), true); + @Nullable XSourcePosition sourcePosition, + boolean isCodeFragmentEvaluationSupported) { + this(session, null, session.getProject(), editorsProvider, text, sourcePosition, isCodeFragmentEvaluationSupported); + } + + public XDebuggerEvaluationDialog(@NotNull XDebuggerEvaluator evaluator, + @NotNull Project project, + @NotNull XDebuggerEditorsProvider editorsProvider, + @NotNull XExpression text, + @Nullable XSourcePosition sourcePosition, + boolean isCodeFragmentEvaluationSupported) { + this(null, () -> evaluator, project, editorsProvider, text, sourcePosition, isCodeFragmentEvaluationSupported); + } + + private XDebuggerEvaluationDialog(@Nullable XDebugSession session, + @Nullable Supplier evaluatorSupplier, + @NotNull Project project, + @NotNull XDebuggerEditorsProvider editorsProvider, + @NotNull XExpression text, + @Nullable XSourcePosition sourcePosition, + boolean isCodeFragmentEvaluationSupported) { + super(WindowManager.getInstance().getFrame(project), true); mySession = session; + myEvaluatorSupplier = evaluatorSupplier; + myProject = project; myEditorsProvider = editorsProvider; mySourcePosition = sourcePosition; + myIsCodeFragmentEvaluationSupported = isCodeFragmentEvaluationSupported; setModal(false); setOKButtonText(XDebuggerBundle.message("xdebugger.button.evaluate")); setCancelButtonText(XDebuggerBundle.message("xdebugger.evaluate.dialog.close")); - mySession.addSessionListener(new XDebugSessionListener() { + if (mySession != null) mySession.addSessionListener(new XDebugSessionListener() { @Override public void sessionStopped() { ApplicationManager.getApplication().invokeLater(() -> close(CANCEL_EXIT_CODE)); @@ -104,8 +129,8 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } }, myDisposable); - myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP, - ((XDebugSessionImpl)session).getValueMarkers()); + myTreePanel = new XDebuggerTreePanel(project, editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP, + session == null ? null : ((XDebugSessionImpl)session).getValueMarkers()); myResultPanel = JBUI.Panels.simplePanel() .addToTop(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.result"))) .addToCenter(myTreePanel.getMainPanel()); @@ -117,7 +142,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { @Override public void update(AnActionEvent e) { Project project = e.getProject(); - e.getPresentation().setEnabled(project != null && LookupManager.getInstance(project).getActiveLookup() == null); + e.getPresentation().setEnabled(session != null && project != null && LookupManager.getInstance(project).getActiveLookup() == null); } @Override @@ -130,7 +155,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { new AnAction() { @Override public void actionPerformed(AnActionEvent e) { - IdeFocusManager.getInstance(mySession.getProject()).requestFocus(myTreePanel.getTree(), true); + IdeFocusManager.getInstance(project).requestFocus(myTreePanel.getTree(), true); } }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.ALT_DOWN_MASK)), getRootPane(), myDisposable); @@ -140,7 +165,6 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { myTreePanel.getTree().selectNodeOnLoad(rootFilter); EvaluationMode mode = XDebuggerSettingManagerImpl.getInstanceImpl().getGeneralSettings().getEvaluationDialogMode(); - myIsCodeFragmentEvaluationSupported = evaluator.isCodeFragmentEvaluationSupported(); if (mode == EvaluationMode.CODE_FRAGMENT && !myIsCodeFragmentEvaluationSupported) { mode = EvaluationMode.EXPRESSION; } @@ -158,6 +182,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } private void updateSourcePosition() { + if (mySession == null) return; ApplicationManager.getApplication().invokeLater(() -> { mySourcePosition = mySession.getCurrentPosition(); getInputEditor().setSourcePosition(mySourcePosition); @@ -176,7 +201,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { @Override public void actionPerformed(ActionEvent e) { super.actionPerformed(e); - if ((e.getModifiers() & ADD_WATCH_MODIFIERS) == ADD_WATCH_MODIFIERS) { + if (mySession != null && (e.getModifiers() & ADD_WATCH_MODIFIERS) == ADD_WATCH_MODIFIERS) { addToWatches(); } } @@ -256,13 +281,12 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } private EvaluationInputComponent createInputComponent(EvaluationMode mode, XExpression text) { - final Project project = mySession.getProject(); text = XExpressionImpl.changeMode(text, mode); if (mode == EvaluationMode.EXPRESSION) { - return new ExpressionInputComponent(project, myEditorsProvider, mySourcePosition, text, myDisposable); + return new ExpressionInputComponent(myProject, myEditorsProvider, mySourcePosition, text, myDisposable, mySession != null); } else { - return new CodeFragmentInputComponent(project, myEditorsProvider, mySourcePosition, text, + return new CodeFragmentInputComponent(myProject, myEditorsProvider, mySourcePosition, text, getDimensionServiceKey() + ".splitter", myDisposable); } } @@ -317,7 +341,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { inputEditor.saveTextInHistory(); XExpression expression = inputEditor.getExpression(); - XDebuggerEvaluator evaluator = mySession.getDebugProcess().getEvaluator(); + XDebuggerEvaluator evaluator = mySession == null ? myEvaluatorSupplier.get() : mySession.getDebugProcess().getEvaluator(); if (evaluator == null) { evaluationCallback.errorOccurred(XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator")); } @@ -327,7 +351,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } public void evaluationDone() { - mySession.rebuildViews(); + if (mySession != null) mySession.rebuildViews(); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java index 477184bad5fd..efcc0f5766ab 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XValueHint.java @@ -45,6 +45,7 @@ import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerUtil; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.ExpressionInfo; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink; import com.intellij.xdebugger.frame.XFullValueEvaluator; @@ -76,28 +77,55 @@ import java.util.concurrent.atomic.AtomicBoolean; public class XValueHint extends AbstractValueHint { private static final Logger LOG = Logger.getInstance(XValueHint.class); + private final XDebuggerEditorsProvider myEditorsProvider; private final XDebuggerEvaluator myEvaluator; private final XDebugSession myDebugSession; private final boolean myFromKeyboard; private final String myExpression; private final String myValueName; - private final @Nullable XSourcePosition myExpressionPosition; - private final ExpressionInfo myExpressionInfo; + private final XSourcePosition myExpressionPosition; private Disposable myDisposable; private static final Key HINT_KEY = Key.create("allows only one value hint per editor"); - public XValueHint(@NotNull Project project, @NotNull Editor editor, @NotNull Point point, @NotNull ValueHintType type, - @NotNull ExpressionInfo expressionInfo, @NotNull XDebuggerEvaluator evaluator, - @NotNull XDebugSession session, boolean fromKeyboard) { - super(project, editor, point, type, expressionInfo.getTextRange()); + public XValueHint(@NotNull Project project, + @NotNull Editor editor, + @NotNull Point point, + @NotNull ValueHintType type, + @NotNull ExpressionInfo expressionInfo, + @NotNull XDebuggerEvaluator evaluator, + @NotNull XDebugSession session, + boolean fromKeyboard) { + this(project, session.getDebugProcess().getEditorsProvider(), editor, point, type, expressionInfo, evaluator, session, fromKeyboard); + } + protected XValueHint(@NotNull Project project, + @NotNull XDebuggerEditorsProvider editorsProvider, + @NotNull Editor editor, + @NotNull Point point, + @NotNull ValueHintType type, + @NotNull ExpressionInfo expressionInfo, + @NotNull XDebuggerEvaluator evaluator, + boolean fromKeyboard) { + this(project, editorsProvider, editor, point, type, expressionInfo, evaluator, null, fromKeyboard); + } + + private XValueHint(@NotNull Project project, + @NotNull XDebuggerEditorsProvider editorsProvider, + @NotNull Editor editor, + @NotNull Point point, + @NotNull ValueHintType type, + @NotNull ExpressionInfo expressionInfo, + @NotNull XDebuggerEvaluator evaluator, + @Nullable XDebugSession session, + boolean fromKeyboard) { + super(project, editor, point, type, expressionInfo.getTextRange()); + myEditorsProvider = editorsProvider; myEvaluator = evaluator; myDebugSession = session; myFromKeyboard = fromKeyboard; myExpression = XDebuggerEvaluateActionHandler.getExpressionText(expressionInfo, editor.getDocument()); myValueName = XDebuggerEvaluateActionHandler.getDisplayText(expressionInfo, editor.getDocument()); - myExpressionInfo = expressionInfo; VirtualFile file; ConsoleView consoleView = ConsoleViewImpl.CONSOLE_VIEW_IN_EDITOR_VIEW.get(editor); @@ -178,13 +206,7 @@ public class XValueHint extends AbstractValueHint { XValueNodeImpl.buildText(valuePresenter, text); if (!hasChildren) { - SimpleColoredComponent component = HintUtil.createInformationComponent(); - text.appendToComponent(component); - if (myFullValueEvaluator != null) { - component.append(myFullValueEvaluator.getLinkText(), XDebuggerTreeNodeHyperlink.TEXT_ATTRIBUTES, - (Consumer)event -> DebuggerUIUtil.showValuePopup(myFullValueEvaluator, event, getProject(), getEditor())); - LinkMouseListenerBase.installSingleTagOn(component); - } + JComponent component = createHintComponent(text, valuePresenter, myFullValueEvaluator); showHint(component); } else if (getType() == ValueHintType.MOUSE_CLICK_HINT) { @@ -242,6 +264,23 @@ public class XValueHint extends AbstractValueHint { }, myExpressionPosition); } + @NotNull + protected JComponent createHintComponent(@NotNull SimpleColoredText text, + @NotNull XValuePresentation presentation, + @Nullable XFullValueEvaluator evaluator) { + SimpleColoredComponent component = HintUtil.createInformationComponent(); + text.appendToComponent(component); + if (evaluator != null) { + component.append( + evaluator.getLinkText(), + XDebuggerTreeNodeHyperlink.TEXT_ATTRIBUTES, + (Consumer)event -> DebuggerUIUtil.showValuePopup(evaluator, event, getProject(), getEditor()) + ); + LinkMouseListenerBase.installSingleTagOn(component); + } + return component; + } + private void disposeVisibleHint() { if (myDisposable != null) { Disposer.dispose(myDisposable); @@ -253,9 +292,9 @@ public class XValueHint extends AbstractValueHint { if (myCurrentHint != null) { myCurrentHint.hide(); } - XValueMarkers valueMarkers = ((XDebugSessionImpl)myDebugSession).getValueMarkers(); - XDebuggerTreeCreator creator = new XDebuggerTreeCreator(myDebugSession.getProject(), myDebugSession.getDebugProcess().getEditorsProvider(), - myDebugSession.getCurrentPosition(), valueMarkers); + XValueMarkers valueMarkers = myDebugSession == null ? null : ((XDebugSessionImpl)myDebugSession).getValueMarkers(); + XSourcePosition position = myDebugSession == null ? null : myDebugSession.getCurrentPosition(); + XDebuggerTreeCreator creator = new XDebuggerTreeCreator(getProject(), myEditorsProvider, position, valueMarkers); showTreePopup(creator, Pair.create(value, myValueName)); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/QuickEvaluateHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/QuickEvaluateHandler.java index 9c64d1af5597..bc1938451631 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/QuickEvaluateHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/common/QuickEvaluateHandler.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger.impl.evaluate.quick.common; +import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,10 @@ public abstract class QuickEvaluateHandler { public abstract boolean isEnabled(@NotNull Project project); + public boolean isEnabled(@NotNull Project project, @NotNull AnActionEvent event) { + return isEnabled(project); + } + @Nullable public abstract AbstractValueHint createValueHint(@NotNull Project project, @NotNull Editor editor, @NotNull Point point, ValueHintType type);