IDEA-127581 Don't crop the string value if there is enough space to display whole string

This commit is contained in:
Egor.Ushakov
2015-02-11 16:58:10 +03:00
parent 1146bc5690
commit 1f1eb161d4
4 changed files with 74 additions and 18 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -36,7 +36,7 @@ public interface XValueNode extends Obsolescent {
* If value text exceeds this constant it's recommended to truncate it and use {@link #setFullValueEvaluator(XFullValueEvaluator)} method
* to provide full value
*/
int MAX_VALUE_LENGTH = 100;
int MAX_VALUE_LENGTH = 1000;
/**
* Setup presentation of the value
@@ -40,6 +40,7 @@ import com.intellij.xdebugger.frame.XFullValueEvaluator;
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.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -328,4 +329,14 @@ public class DebuggerUIUtil {
return myObsolete.get();
}
}
@Nullable
public static String getNodeRawValue(@NotNull XValueNodeImpl valueNode) {
if (valueNode.getValueContainer() instanceof XValueTextProvider) {
return ((XValueTextProvider)valueNode.getValueContainer()).getValueText();
}
else {
return valueNode.getRawValue();
}
}
}
@@ -15,18 +15,24 @@
*/
package com.intellij.xdebugger.impl.ui.tree;
import com.intellij.openapi.project.Project;
import com.intellij.ui.AbstractExpandableItemsHandler;
import com.intellij.ui.ColoredTreeCellRenderer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ui.JBInsets;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.ImmediateFullValueEvaluator;
import com.intellij.xdebugger.frame.XDebuggerTreeNodeHyperlink;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.MouseEvent;
/**
* @author nik
@@ -37,6 +43,8 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
private int myLinkOffset;
private int myLinkWidth;
private final MyLongTextHyperlink myLongTextLink = new MyLongTextHyperlink();
public XDebuggerTreeRenderer() {
Insets myLinkIpad = myLink.getIpad();
myLink.setIpad(new JBInsets(myLinkIpad.top, 0, myLinkIpad.bottom, myLinkIpad.right));
@@ -56,18 +64,37 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
XDebuggerTreeNode node = (XDebuggerTreeNode)value;
node.appendToComponent(this);
setIcon(node.getIcon());
Rectangle treeVisibleRect = tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? ((XDebuggerTree.LinkTreeUI)tree.getUI()).getRowX(row, path.getPathCount() - 1) : 0;
if (myHaveLink) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;
myLink.setBounds(0, 0, linkSize.width, linkSize.height);
Rectangle treeVisibleRect = tree.getVisibleRect();
TreePath path = tree.getPathForRow(row);
int rowX = path != null ? ((XDebuggerTree.LinkTreeUI)tree.getUI()).getRowX(row, path.getPathCount() - 1) : 0;
myLinkOffset = Math.min(super.getPreferredSize().width, treeVisibleRect.x + treeVisibleRect.width - myLinkWidth - rowX);
setupLinkDimensions(treeVisibleRect, rowX);
}
else {
if (rowX + super.getPreferredSize().width > treeVisibleRect.x + treeVisibleRect.width) {
// text does not fit visible area - show link
if (node instanceof XValueNodeImpl) {
final String rawValue = DebuggerUIUtil.getNodeRawValue((XValueNodeImpl)node);
if (rawValue != null) {
myLongTextLink.setupComponent(rawValue, ((XDebuggerTree)tree).getProject());
append(myLongTextLink.getLinkText(), myLongTextLink.getTextAttributes(), myLongTextLink);
setupLinkDimensions(treeVisibleRect, rowX);
}
}
}
}
putClientProperty(AbstractExpandableItemsHandler.DISABLE_EXPANDABLE_HANDLER, myHaveLink ? true : null);
}
private void setupLinkDimensions(Rectangle treeVisibleRect, int rowX) {
Dimension linkSize = myLink.getPreferredSize();
myLinkWidth = linkSize.width;
myLink.setBounds(0, 0, linkSize.width, linkSize.height);
myLinkOffset = Math.min(super.getPreferredSize().width, treeVisibleRect.x + treeVisibleRect.width - myLinkWidth - rowX);
}
@Override
public void append(@NotNull String fragment, @NotNull SimpleTextAttributes attributes, Object tag) {
if (tag instanceof XDebuggerTreeNodeHyperlink && ((XDebuggerTreeNodeHyperlink)tag).alwaysOnScreen()) {
@@ -131,4 +158,29 @@ class XDebuggerTreeRenderer extends ColoredTreeCellRenderer {
super.doPaint(g);
}
}
private static class MyLongTextHyperlink extends XDebuggerTreeNodeHyperlink {
private String myText;
private Project myProject;
public MyLongTextHyperlink() {
super(XDebuggerBundle.message("node.test.show.full.value"));
}
public void setupComponent(String text, Project project) {
myText = text;
myProject = project;
}
@Override
public boolean alwaysOnScreen() {
return true;
}
@Override
public void onClick(MouseEvent event) {
DebuggerUIUtil.showValuePopup(new ImmediateFullValueEvaluator(myText), event, myProject, null);
event.consume();
}
}
}
@@ -23,7 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.AppUIUtil;
import com.intellij.util.SmartList;
import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.impl.ui.XValueTextProvider;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.nodes.HeadlessValueEvaluationCallback;
import com.intellij.xdebugger.impl.ui.tree.nodes.WatchMessageNode;
@@ -76,14 +76,7 @@ public abstract class XFetchValueActionBase extends AnAction {
XValueNodeImpl valueNode = (XValueNodeImpl)node;
XFullValueEvaluator fullValueEvaluator = valueNode.getFullValueEvaluator();
if (fullValueEvaluator == null || !fullValueEvaluator.isShowValuePopup()) {
String rawValue;
if (valueNode.getValueContainer() instanceof XValueTextProvider) {
rawValue = ((XValueTextProvider)valueNode.getValueContainer()).getValueText();
}
else {
rawValue = valueNode.getRawValue();
}
valueCollector.add(StringUtil.notNullize(rawValue));
valueCollector.add(StringUtil.notNullize(DebuggerUIUtil.getNodeRawValue(valueNode)));
}
else {
new CopyValueEvaluationCallback(valueNode, valueCollector).startFetchingValue(fullValueEvaluator);