extracted non java specific code from value markers in debugger

This commit is contained in:
nik
2011-04-15 13:25:33 +04:00
parent b5774a2924
commit e09ae18d6b
15 changed files with 253 additions and 143 deletions
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.actions;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
@@ -25,19 +26,23 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.idea.ActionsBundle;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.Ref;
import com.intellij.util.containers.HashMap;
import com.sun.jdi.*;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -48,6 +53,7 @@ import java.util.Map;
*/
public class MarkObjectAction extends DebuggerAction {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.MarkObjectAction");
public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit
private final String MARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.text");
private final String UNMARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.unmark.text");
@@ -79,13 +85,17 @@ public class MarkObjectAction extends DebuggerAction {
valueDescriptor.setMarkup(debugProcess, null);
}
else {
final ValueMarkup suggestedMarkup = new ValueMarkup(valueDescriptor.getName(), Color.RED);
final String defaultText = valueDescriptor.getName();
final Ref<Pair<ValueMarkup,Boolean>> result = new Ref<Pair<ValueMarkup, Boolean>>(null);
try {
final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue());
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
result.set(ObjectMarkupPropertiesDialog.chooseMarkup(suggestedMarkup, suggestAdditionalMarkup));
ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(defaultText, suggestAdditionalMarkup);
dialog.show();
if (dialog.isOK()) {
result.set(Pair.create(dialog.getConfiguredMarkup(), dialog.isMarkAdditionalFields()));
}
}
});
}
@@ -176,7 +186,7 @@ public class MarkObjectAction extends DebuggerAction {
final ValueMarkup markup = result.get((ObjectReference)fieldValue);
final String fieldName = field.name();
final Color autoMarkupColor = ValueMarkup.getAutoMarkupColor();
final Color autoMarkupColor = getAutoMarkupColor();
if (markup == null) {
result.put((ObjectReference)fieldValue, new ValueMarkup(fieldName, autoMarkupColor, createMarkupTooltipText(null, refType, fieldName)));
}
@@ -197,8 +207,9 @@ public class MarkObjectAction extends DebuggerAction {
// invoke the following method using Reflection in order to remain compilable on jdk 1.5
// java.util.List<com.sun.jdi.ObjectReference> referringObjects(long l);
try {
final java.lang.reflect.Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
return (List<ObjectReference>)apiMethod.invoke(value, ValueMarkup.AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
final Method apiMethod = ObjectReference.class.getMethod("referringObjects", long.class);
//noinspection unchecked
return (List<ObjectReference>)apiMethod.invoke(value, AUTO_MARKUP_REFERRING_OBJECTS_LIMIT);
}
catch (IllegalAccessException e) {
LOG.error(e); // should not happen
@@ -211,7 +222,7 @@ public class MarkObjectAction extends DebuggerAction {
return Collections.emptyList();
}
private static String createMarkupTooltipText(String prefix, ReferenceType refType, String fieldName) {
private static String createMarkupTooltipText(@Nullable String prefix, ReferenceType refType, String fieldName) {
final StringBuilder builder = new StringBuilder();
if (prefix == null) {
builder.append("Value referenced from:");
@@ -241,4 +252,10 @@ public class MarkObjectAction extends DebuggerAction {
presentation.setVisible(enable);
presentation.setText(text);
}
public static Color getAutoMarkupColor() {
final EditorColorsManager manager = EditorColorsManager.getInstance();
final TextAttributes textAttributes = manager.getGlobalScheme().getAttributes(HighlightInfoType.STATIC_FIELD.getAttributesKey());
return textAttributes.getForegroundColor();
}
}
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.debugger.actions.ObjectMarkupPropertiesDialog">
<grid id="27dc6" binding="myAdditionalPropertiesPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="5" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="372" height="96"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="1dc00" class="com.intellij.openapi.ui.ex.MultiLineLabel" binding="myDescriptionLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
<component id="d6e49" class="javax.swing.JCheckBox" binding="myCbMarkAdditionalFields">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="&amp;Mark values referenced from constant fields"/>
</properties>
</component>
</children>
</grid>
</form>
@@ -15,140 +15,56 @@
*/
package com.intellij.debugger.actions;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.FixedSizeButton;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.ui.ex.MultiLineLabel;
import com.intellij.openapi.util.Pair;
import com.intellij.ui.ColorChooser;
import com.intellij.ui.DocumentAdapter;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.Alarm;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
/**
* @author Eugene Zhuravlev
* Date: Feb 4, 2007
*/
public class ObjectMarkupPropertiesDialog extends DialogWrapper {
private final JTextField myTextMarkupField;
private final JCheckBox myCbMarkAdditionalFields;
private final SimpleColoredComponent myColorSample;
private SimpleTextAttributes myAttributes;
private final Alarm myUpdateAlarm;
private static final int UPDATE_DELAY = 200;
private static Boolean ourMarkCbSavedState;
public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialog {
@NonNls private static final String MARK_ALL_REFERENCED_VALUES_KEY = "debugger.mark.all.referenced.values";
private JCheckBox myCbMarkAdditionalFields;
private final boolean mySuggestAdditionalMarkup;
private JPanel myAdditionalPropertiesPanel;
private MultiLineLabel myDescriptionLabel;
public ObjectMarkupPropertiesDialog(@NotNull final ValueMarkup suggestion, boolean suggestAdditionalMarkup) {
super(true);
public ObjectMarkupPropertiesDialog(@NotNull final String defaultText, boolean suggestAdditionalMarkup) {
super(defaultText);
mySuggestAdditionalMarkup = suggestAdditionalMarkup;
setTitle("Select object label");
setModal(true);
myTextMarkupField = new JTextField(30);
myCbMarkAdditionalFields = new JCheckBox("Mark values referenced from constant fields", ourMarkCbSavedState == null? suggestAdditionalMarkup : ourMarkCbSavedState);
myCbMarkAdditionalFields.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent e) {
ourMarkCbSavedState = myCbMarkAdditionalFields.isSelected();
}
});
myColorSample = new SimpleColoredComponent();
myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
myAttributes = createAttributes(suggestion.getColor());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
myTextMarkupField.setText(suggestion.getText().trim());
updateLabelSample(0);
}
});
myDescriptionLabel.setText("If the value is referenced by a constant field of an abstract class,\n" +
"IDEA could additionally mark all values referenced from this class with the names of referencing fields.");
myCbMarkAdditionalFields.setSelected(PropertiesComponent.getInstance().getBoolean(MARK_ALL_REFERENCED_VALUES_KEY, true));
init();
}
public JComponent getPreferredFocusedComponent() {
return myTextMarkupField;
}
protected void dispose() {
myUpdateAlarm.dispose();
super.dispose();
}
@Nullable
protected JComponent createCenterPanel() {
final JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.add(new JLabel("Label:"), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
mainPanel.add(myTextMarkupField, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
final JPanel samplePanel = new JPanel(new BorderLayout());
samplePanel.add(myColorSample, BorderLayout.CENTER);
samplePanel.setBorder(BorderFactory.createEtchedBorder());
final FixedSizeButton chooseColorButton = new FixedSizeButton(samplePanel);
double weighty = mySuggestAdditionalMarkup ? 0.0 : 1.0;
mainPanel.add(new JLabel("Preview: "), new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
mainPanel.add(samplePanel, new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 1.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 0), 0, 0));
mainPanel.add(chooseColorButton, new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, weighty, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
@Override
protected void doOKAction() {
if (mySuggestAdditionalMarkup) {
final JPanel panel = new JPanel(new BorderLayout());
panel.add(new MultiLineLabel(
"If the value is referenced by a constant field of an abstract class,\nIDEA could additionally mark all values referenced from this class with the names of referencing fields."
), BorderLayout.CENTER);
panel.add(myCbMarkAdditionalFields, BorderLayout.SOUTH);
myCbMarkAdditionalFields.setMnemonic('M');
mainPanel.add(panel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 0.0, 1.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 0, 0), 0, 0));
PropertiesComponent.getInstance().setValue(MARK_ALL_REFERENCED_VALUES_KEY, Boolean.toString(myCbMarkAdditionalFields.isSelected()));
}
myTextMarkupField.getDocument().addDocumentListener(new DocumentAdapter() {
protected void textChanged(final DocumentEvent e) {
updateLabelSample(UPDATE_DELAY);
}
});
chooseColorButton.addActionListener(new ActionListener() {
public void actionPerformed(final ActionEvent e) {
final Color color = ColorChooser.chooseColor(myColorSample, "Choose label color", null);
myAttributes = createAttributes(color);
updateLabelSample(UPDATE_DELAY);
}
});
return mainPanel;
super.doOKAction();
}
private void updateLabelSample(final int updateDelay) {
myUpdateAlarm.cancelAllRequests();
myUpdateAlarm.addRequest(new Runnable() {
public void run() {
myColorSample.clear();
myColorSample.append(myTextMarkupField.getText().trim(), myAttributes);
myColorSample.repaint();
}
}, updateDelay);
}
public static Pair<ValueMarkup,Boolean> chooseMarkup(ValueMarkup suggestion, boolean suggestAdditionalMarkup) {
final ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(suggestion, suggestAdditionalMarkup);
dialog.show();
if (dialog.isOK()) {
final String text = dialog.myTextMarkupField.getText().trim();
final Color color = dialog.myAttributes.getFgColor();
return text.length() > 0? new Pair<ValueMarkup, Boolean>(new ValueMarkup(text, color, suggestion.getToolTipText()), dialog.myCbMarkAdditionalFields.isSelected()) : null;
@Override
protected JComponent createCenterPanel() {
JComponent mainPanel = super.createCenterPanel();
if (!mySuggestAdditionalMarkup) {
return mainPanel;
}
return null;
JPanel panel = new JPanel(new BorderLayout());
panel.add(BorderLayout.CENTER, mainPanel);
panel.add(BorderLayout.SOUTH, myAdditionalPropertiesPanel);
return panel;
}
private static SimpleTextAttributes createAttributes(final Color color) {
return new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, color);
public boolean isMarkAdditionalFields() {
return myCbMarkAdditionalFields.isSelected();
}
}
@@ -18,7 +18,7 @@ package com.intellij.debugger.engine.evaluation;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
@@ -20,7 +20,7 @@ import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.ui.impl.watch.*;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ColoredTreeCellRenderer;
@@ -16,7 +16,7 @@
package com.intellij.debugger.ui.impl;
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.util.Comparing;
@@ -29,7 +29,7 @@ import com.intellij.debugger.ui.impl.tree.TreeBuilderNode;
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
import com.intellij.openapi.application.ApplicationManager;
@@ -21,7 +21,7 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Key;
@@ -25,7 +25,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.settings.ThreadsViewSettings;
import com.intellij.debugger.ui.tree.StackFrameDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.roots.ProjectFileIndex;
@@ -29,7 +29,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.ValueMarkup;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.debugger.ui.tree.render.ClassRenderer;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
@@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.psi.PsiExpression;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.sun.jdi.Value;
import org.jetbrains.annotations.Nullable;
@@ -1,67 +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.tree;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.markup.TextAttributes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
/**
* @author Eugene Zhuravlev
* Date: Jan 27, 2007
*/
public class ValueMarkup {
public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit
private final String myText;
private final Color myColor;
@Nullable
private final String myToolTipText;
public ValueMarkup(final String text, final Color color) {
this(text, color, null);
}
public ValueMarkup(final String text, final Color color, String toolTipText) {
myText = text;
myColor = color;
myToolTipText = toolTipText;
}
@NotNull
public String getText() {
return myText;
}
public Color getColor() {
return myColor;
}
@Nullable
public String getToolTipText() {
return myToolTipText;
}
public static Color getAutoMarkupColor() {
final EditorColorsManager manager = EditorColorsManager.getInstance();
final TextAttributes textAttributes = manager.getGlobalScheme().getAttributes(HighlightInfoType.STATIC_FIELD.getAttributesKey());
return textAttributes.getForegroundColor();
}
}