diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index bf63f833b23e..22573df059af 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -15,20 +15,30 @@ */ package com.intellij.debugger.actions; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.JavaValue; +import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.editor.event.DocumentAdapter; +import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.ui.EditorTextField; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.components.BorderLayoutPanel; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.TextViewer; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; import com.intellij.xdebugger.impl.ui.tree.actions.XFetchValueActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.*; +import java.util.List; /* * @author Jeka @@ -45,16 +55,38 @@ public class ViewTextAction extends XFetchValueActionBase { @Override public void handleInCollector(Project project, String value, XDebuggerTree tree) { + String text = StringUtil.unquoteString(value); if (dialog == null) { - dialog = new MyDialog(project); - dialog.setTitle("View Text"); + XValueNodeImpl node = getStringNode(e); + dialog = new MyDialog(project, text, node); + dialog.setTitle(ActionsBundle.message(node != null ? "action.Debugger.ViewEditText.text" : "action.Debugger.ViewText.text")); dialog.show(); } - dialog.setText(StringUtil.unquoteString(value)); + dialog.setText(text); } }; } + @Override + public void update(@NotNull AnActionEvent e) { + super.update(e); + if (getStringNode(e) != null) { + e.getPresentation().setText(ActionsBundle.message("action.Debugger.ViewEditText.text")); + } + } + + private static XValueNodeImpl getStringNode(@NotNull AnActionEvent e) { + List selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(e.getDataContext()); + if (selectedNodes.size() == 1) { + XValueNodeImpl node = selectedNodes.get(0); + XValue container = node.getValueContainer(); + if (container instanceof JavaValue && ((JavaValue)container).getDescriptor().isString() && container.getModifier() != null) { + return node; + } + } + return null; + } + //@Override //protected void processText(final Project project, final String text, DebuggerTreeNodeImpl node, DebuggerContextImpl debuggerContext) { // final NodeDescriptorImpl descriptor = node.getDescriptor(); @@ -66,15 +98,27 @@ public class ViewTextAction extends XFetchValueActionBase { //} private static class MyDialog extends DialogWrapper { - private final EditorTextField myTextViewer; + private final TextViewer myTextViewer; + private final XValueNodeImpl myStringNode; - private MyDialog(Project project) { + private MyDialog(Project project, String initialValue, XValueNodeImpl stringNode) { super(project, false); + myStringNode = stringNode; setModal(false); setCancelButtonText("Close"); + setOKButtonText("Set"); + getOKAction().setEnabled(false); setCrossClosesWindow(true); - myTextViewer = new TextViewer(project, true, true); + myTextViewer = new TextViewer(initialValue, project, myStringNode == null); + myTextViewer.addDocumentListener(new DocumentAdapter() { + @Override + public void documentChanged(DocumentEvent e) { + if (e.getNewLength() + e.getOldLength() > 0) { + getOKAction().setEnabled(true); + } + } + }); init(); } @@ -82,10 +126,20 @@ public class ViewTextAction extends XFetchValueActionBase { myTextViewer.setText(text); } + @Override + protected void doOKAction() { + if (myStringNode != null) { + DebuggerUIUtil.setTreeNodeValue(myStringNode, + StringUtil.wrapWithDoubleQuote(DebuggerUtils.translateStringValue(myTextViewer.getText())), + errorMessage -> Messages.showErrorDialog(myStringNode.getTree(), errorMessage)); + } + super.doOKAction(); + } + @Override @NotNull protected Action[] createActions() { - return new Action[] {getCancelAction()}; + return myStringNode != null ? new Action[]{getOKAction(), getCancelAction()} : new Action[]{getCancelAction()}; } @Nullable @@ -101,8 +155,7 @@ public class ViewTextAction extends XFetchValueActionBase { @Override protected JComponent createCenterPanel() { - final JPanel panel = new JPanel(new BorderLayout()); - panel.add(myTextViewer, BorderLayout.CENTER); + BorderLayoutPanel panel = JBUI.Panels.simplePanel(myTextViewer); panel.setPreferredSize(JBUI.size(300, 200)); return panel; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeInplaceEditor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeInplaceEditor.java deleted file mode 100644 index 26801ccdfff6..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeInplaceEditor.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2000-2009 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.debugger.ui.impl.watch; - -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.impl.ui.tree.TreeInplaceEditor; - -import javax.swing.*; -import javax.swing.tree.TreePath; - -public abstract class DebuggerTreeInplaceEditor extends TreeInplaceEditor { - private final DebuggerTreeNodeImpl myNode; - - protected Project getProject() { - return myNode.getTree().getProject(); - } - - public DebuggerTreeInplaceEditor(DebuggerTreeNodeImpl node) { - myNode = node; - } - - protected TreePath getNodePath() { - return new TreePath(myNode.getPath()); - } - - protected JTree getTree() { - return myNode.getTree(); - } - - @Override - protected void onShown() { - myNode.getTree().onEditorShown(myNode); - } - - @Override - protected void onHidden() { - myNode.getTree().onEditorHidden(myNode); - } -} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 3e94ee271249..ae6d3f2747f7 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1027,6 +1027,7 @@ group.XDebugger.settings.text=Settings action.Debugger.AdjustArrayRange.text=Adjust Range... action.Debugger.Inspect.text=Inspect action.Debugger.CopyValue.text=Copy Value +action.Debugger.ViewEditText.text=View/Edit Text action.Debugger.ViewText.text=View Text action.Debugger.ViewText.description=View text value of selected node in a separate pane action.Debugger.ShowReferring.text=Show Referring Objects 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 4764e4047bc7..f9728611db03 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 @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.ui; import com.intellij.codeInsight.hint.HintUtil; +import com.intellij.ide.DataManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; @@ -38,6 +39,7 @@ import com.intellij.ui.EditorTextField; import com.intellij.ui.ScreenUtil; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.popup.list.ListPopupImpl; +import com.intellij.util.Consumer; import com.intellij.xdebugger.Obsolescent; import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.XDebuggerManager; @@ -48,9 +50,13 @@ import com.intellij.xdebugger.breakpoints.XBreakpointListener; import com.intellij.xdebugger.breakpoints.XBreakpointManager; import com.intellij.xdebugger.frame.XFullValueEvaluator; import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.frame.XValueModifier; +import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointsDialogFactory; import com.intellij.xdebugger.impl.breakpoints.ui.XLightBreakpointPropertiesPanel; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; +import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -406,4 +412,35 @@ public class DebuggerUIUtil { public static boolean isObsolete(Object object) { return object instanceof Obsolescent && ((Obsolescent)object).isObsolete(); } + + public static void setTreeNodeValue(XValueNodeImpl valueNode, String text, Consumer errorConsumer) { + XDebuggerTree tree = valueNode.getTree(); + Project project = tree.getProject(); + XValueModifier modifier = valueNode.getValueContainer().getModifier(); + if (modifier == null) return; + XDebuggerTreeState treeState = XDebuggerTreeState.saveState(tree); + valueNode.setValueModificationStarted(); + modifier.setValue(text, new XValueModifier.XModificationCallback() { + @Override + public void valueModified() { + if (isDetachedTree(tree)) { + AppUIUtil.invokeOnEdt(() -> tree.rebuildAndRestore(treeState)); + } + XDebuggerUtilImpl.rebuildAllSessionsViews(project); + } + + @Override + public void errorOccurred(@NotNull final String errorMessage) { + AppUIUtil.invokeOnEdt(() -> { + tree.rebuildAndRestore(treeState); + errorConsumer.consume(errorMessage); + }); + XDebuggerUtilImpl.rebuildAllSessionsViews(project); + } + + boolean isDetachedTree(XDebuggerTree tree) { + return XDebugSessionTab.TAB_KEY.getData(DataManager.getInstance().getDataContext(tree)) == null; + } + }); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java index 112425d6b84d..bd32c766e0d8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/TextViewer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 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. @@ -29,26 +29,24 @@ import javax.swing.*; public final class TextViewer extends EditorTextField { private final boolean myEmbeddedIntoDialogWrapper; - private final boolean myUseSoftWraps; - public TextViewer(@NotNull Project project, boolean embeddedIntoDialogWrapper, boolean useSoftWraps) { - this(createDocument(""), project, embeddedIntoDialogWrapper, useSoftWraps); + public TextViewer(@NotNull String initialText, @NotNull Project project, boolean viewer) { + this(createDocument(initialText), project, true, viewer); } public TextViewer(@NotNull String initialText, @NotNull Project project) { - this(createDocument(initialText), project, false, true); + this(initialText, project, true); } - public TextViewer(@NotNull Document document, @NotNull Project project, boolean embeddedIntoDialogWrapper, boolean useSoftWraps) { - super(document, project, FileTypes.PLAIN_TEXT, true, false); + public TextViewer(@NotNull Document document, @NotNull Project project, boolean embeddedIntoDialogWrapper, boolean viewer) { + super(document, project, FileTypes.PLAIN_TEXT, viewer, false); myEmbeddedIntoDialogWrapper = embeddedIntoDialogWrapper; - myUseSoftWraps = useSoftWraps; setFontInheritedFromLAF(false); } private static Document createDocument(@NotNull String initialText) { - final Document document = EditorFactory.getInstance().createDocument(initialText); + final Document document = EditorFactory.getInstance().createDocument(StringUtil.convertLineSeparators(initialText)); //if (document instanceof DocumentImpl) { // ((DocumentImpl)document).setAcceptSlashR(true); //} @@ -68,7 +66,7 @@ public final class TextViewer extends EditorTextField { editor.getScrollPane().setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); editor.setEmbeddedIntoDialogWrapper(myEmbeddedIntoDialogWrapper); editor.getComponent().setPreferredSize(null); - editor.getSettings().setUseSoftWraps(myUseSoftWraps); + editor.getSettings().setUseSoftWraps(true); editor.setColorsScheme(DebuggerUIUtil.getColorScheme()); return editor; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java index 9352e3f9db07..c353e0148856 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java @@ -16,16 +16,14 @@ package com.intellij.xdebugger.impl.ui.tree; import com.intellij.codeInsight.hint.HintManager; -import com.intellij.ide.DataManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.ui.Messages; import com.intellij.ui.AppUIUtil; import com.intellij.ui.SimpleColoredComponent; import com.intellij.xdebugger.frame.XValueModifier; import com.intellij.xdebugger.frame.presentation.XValuePresentation; -import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; -import com.intellij.xdebugger.impl.ui.XDebugSessionTab; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil; @@ -93,37 +91,17 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor { if (myModifier == null) return; myExpressionEditor.saveTextInHistory(); - final XDebuggerTreeState treeState = XDebuggerTreeState.saveState(myTree); - myValueNode.setValueModificationStarted(); - myModifier.setValue(myExpressionEditor.getExpression().getExpression(), new XValueModifier.XModificationCallback() { - @Override - public void valueModified() { - if (isDetachedTree(myTree)) { - AppUIUtil.invokeOnEdt(() -> myTree.rebuildAndRestore(treeState)); - } - XDebuggerUtilImpl.rebuildAllSessionsViews(getProject()); + + DebuggerUIUtil.setTreeNodeValue(myValueNode, myExpressionEditor.getExpression().getExpression(), errorMessage -> { + Editor editor = myExpressionEditor.getEditor(); + if (editor != null) { + HintManager.getInstance().showErrorHint(editor, errorMessage); } - - @Override - public void errorOccurred(@NotNull final String errorMessage) { - AppUIUtil.invokeOnEdt(() -> { - myTree.rebuildAndRestore(treeState); - - Editor editor = myExpressionEditor.getEditor(); - if (editor != null) { - HintManager.getInstance().showErrorHint(editor, errorMessage); - } - else { - Messages.showErrorDialog(myTree, errorMessage); - } - }); - XDebuggerUtilImpl.rebuildAllSessionsViews(getProject()); - } - - boolean isDetachedTree(XDebuggerTree tree) { - return XDebugSessionTab.TAB_KEY.getData(DataManager.getInstance().getDataContext(tree)) == null; + else { + Messages.showErrorDialog(myTree, errorMessage); } }); + super.doOKAction(); } }