From 1f1eb161d49f6f1b7ce1d7a38b69217c85702887 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 11 Feb 2015 16:56:11 +0300 Subject: [PATCH] IDEA-127581 Don't crop the string value if there is enough space to display whole string --- .../intellij/xdebugger/frame/XValueNode.java | 4 +- .../xdebugger/impl/ui/DebuggerUIUtil.java | 11 ++++ .../impl/ui/tree/XDebuggerTreeRenderer.java | 66 +++++++++++++++++-- .../tree/actions/XFetchValueActionBase.java | 11 +--- 4 files changed, 74 insertions(+), 18 deletions(-) diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java index e50de966192d..5d63f0beddb5 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/frame/XValueNode.java @@ -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 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 f2fd5edf907e..c4c7ab6a148b 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 @@ -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(); + } + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java index ee95281b6c9d..a133739a31c7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/XDebuggerTreeRenderer.java @@ -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(); + } + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java index e155ee5a02ad..bd7c2ff75200 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java @@ -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);