fixed XValueHint value trimming
[idea/community.git] / platform / xdebugger-impl / src / com / intellij / xdebugger / impl / evaluate / quick / XValueHint.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.xdebugger.impl.evaluate.quick;
17
18 import com.intellij.codeInsight.hint.HintUtil;
19 import com.intellij.openapi.diagnostic.Logger;
20 import com.intellij.openapi.editor.Document;
21 import com.intellij.openapi.editor.Editor;
22 import com.intellij.openapi.fileEditor.FileDocumentManager;
23 import com.intellij.openapi.project.Project;
24 import com.intellij.openapi.util.Pair;
25 import com.intellij.openapi.util.TextRange;
26 import com.intellij.openapi.vfs.VirtualFile;
27 import com.intellij.ui.SimpleColoredText;
28 import com.intellij.ui.SimpleTextAttributes;
29 import com.intellij.xdebugger.XDebugSession;
30 import com.intellij.xdebugger.XDebuggerUtil;
31 import com.intellij.xdebugger.XSourcePosition;
32 import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
33 import com.intellij.xdebugger.frame.XFullValueEvaluator;
34 import com.intellij.xdebugger.frame.XValue;
35 import com.intellij.xdebugger.frame.XValueNode;
36 import com.intellij.xdebugger.impl.actions.XDebuggerActions;
37 import com.intellij.xdebugger.impl.evaluate.quick.common.AbstractValueHint;
38 import com.intellij.xdebugger.impl.evaluate.quick.common.ValueHintType;
39 import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
40 import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
41 import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
42 import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
43 import org.jetbrains.annotations.NonNls;
44 import org.jetbrains.annotations.NotNull;
45 import org.jetbrains.annotations.Nullable;
46
47 import javax.swing.*;
48 import java.awt.*;
49
50 /**
51  * @author nik
52  */
53 public class XValueHint extends AbstractValueHint {
54   private static final Logger LOG = Logger.getInstance("#com.intellij.xdebugger.impl.evaluate.quick.XValueHint");
55   private static final int MAX_HINT_LENGTH = 512;
56
57   private final XDebuggerEvaluator myEvaluator;
58   private final XDebugSession myDebugSession;
59   private final String myExpression;
60   private final @Nullable XSourcePosition myExpressionPosition;
61
62   public XValueHint(final Project project, final Editor editor, final Point point, final ValueHintType type, final TextRange textRange,
63                     final XDebuggerEvaluator evaluator, final XDebugSession session) {
64     super(project, editor, point, type, textRange);
65     myEvaluator = evaluator;
66     myDebugSession = session;
67     final Document document = editor.getDocument();
68     myExpression = document.getText(textRange);
69     final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
70     myExpressionPosition = file != null ? XDebuggerUtil.getInstance().createPositionByOffset(file, textRange.getStartOffset()) : null;
71   }
72
73
74   protected boolean canShowHint() {
75     return true;
76   }
77
78   protected void evaluateAndShowHint() {
79     myEvaluator.evaluate(myExpression, new XEvaluationCallbackBase() {
80       public void evaluated(@NotNull final XValue result) {
81         result.computePresentation(new XValueNode() {
82           public void setPresentation(@NonNls @NotNull final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String value,
83                                       final boolean hasChildren) {
84             setPresentation(name, icon, type, XDebuggerUIConstants.EQ_TEXT, value, hasChildren);
85           }
86
87           public void setPresentation(@NonNls @NotNull final String name, @Nullable final Icon icon, @NonNls @Nullable final String type, @NonNls @NotNull final String separator,
88                                       @NonNls @NotNull final String value,
89                                       final boolean hasChildren) {
90             DebuggerUIUtil.invokeOnEventDispatch(new Runnable() {
91               public void run() {
92                 doShowHint(result, name, separator, value, hasChildren);
93               }
94             });
95           }
96
97           public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
98             //todo[nik] implement?
99           }
100
101           public boolean isObsolete() {
102             //todo[nik]
103             return false;
104           }
105         });
106       }
107
108       public void errorOccurred(@NotNull final String errorMessage) {
109         LOG.debug("Cannot evaluate '" + myExpression + "':" + errorMessage);
110       }
111     }, myExpressionPosition);
112   }
113
114   private void doShowHint(final XValue xValue, final String name, final String separator, final String value, final boolean hasChildren) {
115     if (isHintHidden()) return;
116
117     SimpleColoredText text = new SimpleColoredText();
118     text.append(name, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
119     text.append(separator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
120     text.append(value, SimpleTextAttributes.REGULAR_ATTRIBUTES);
121
122     JComponent component;
123     if (!hasChildren) {
124       component = HintUtil.createInformationLabel(text);
125     }
126     else {
127       component = createExpandableHintComponent(text, new Runnable() {
128         public void run() {
129           showTree(xValue, name);
130         }
131       });
132     }
133     showHint(component);
134   }
135
136   private void showTree(final XValue value, final String name) {
137     XDebuggerTree tree = new XDebuggerTree(myDebugSession, myDebugSession.getDebugProcess().getEditorsProvider(),
138                                            myDebugSession.getCurrentPosition(), XDebuggerActions.VALUE_HINT_TREE_POPUP_GROUP);
139     tree.getModel().addTreeModelListener(createTreeListener(tree));
140     XValueHintTreeComponent component = new XValueHintTreeComponent(this, tree, Pair.create(value, name));
141     showTreePopup(component, tree, name);
142   }
143 }