diff --git a/openapi/src/com/intellij/debugger/engine/DebugProcess.java b/openapi/src/com/intellij/debugger/engine/DebugProcess.java
index 3767310fb736..bc92301321ba 100644
--- a/openapi/src/com/intellij/debugger/engine/DebugProcess.java
+++ b/openapi/src/com/intellij/debugger/engine/DebugProcess.java
@@ -4,15 +4,12 @@
*/
package com.intellij.debugger.engine;
-import com.intellij.debugger.engine.DebugProcessListener;
-import com.intellij.debugger.engine.SuspendContext;
+import com.intellij.debugger.PositionManager;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
-import com.intellij.debugger.engine.managerThread.DebuggerManagerThread;
import com.intellij.debugger.engine.jdi.VirtualMachineProxy;
+import com.intellij.debugger.engine.managerThread.DebuggerManagerThread;
import com.intellij.debugger.requests.RequestManager;
-import com.intellij.debugger.ui.tree.render.NodeRendererManager;
-import com.intellij.debugger.PositionManager;
import com.intellij.execution.ExecutionResult;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
@@ -33,8 +30,6 @@ public interface DebugProcess {
Project getProject();
- NodeRendererManager getNodeRendererManager();
-
RequestManager getRequestsManager();
PositionManager getPositionManager();
@@ -78,4 +73,5 @@ public interface DebugProcess {
List paramList) throws EvaluateException;
boolean isAttached();
+
}
diff --git a/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java b/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
index 034d04bc9e4d..3f0be292ec36 100644
--- a/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
+++ b/openapi/src/com/intellij/debugger/engine/DebuggerUtils.java
@@ -200,7 +200,9 @@ public abstract class DebuggerUtils implements ApplicationComponent {
public static Type getSuperType(Type subType, String superType) {
if("java.lang.Object".equals(superType)) {
List list = subType.virtualMachine().classesByName("java.lang.Object");
- if(list.size() > 0) return (ReferenceType)list.get(0);
+ if(list.size() > 0) {
+ return (ReferenceType)list.get(0);
+ }
return null;
}
@@ -253,7 +255,9 @@ public abstract class DebuggerUtils implements ApplicationComponent {
//only for interfaces and arrays
if("java.lang.Object".equals(superType)) {
List list = subType.virtualMachine().classesByName("java.lang.Object");
- if(list.size() > 0) return (ReferenceType)list.get(0);
+ if(list.size() > 0) {
+ return (ReferenceType)list.get(0);
+ }
}
return null;
}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java b/openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java
deleted file mode 100644
index ca7ebe93eab4..000000000000
--- a/openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
- * Use is subject to license terms.
- */
-package com.intellij.debugger.ui.tree.render;
-
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizerUtil;
-import com.intellij.openapi.util.WriteExternalException;
-import org.jdom.Element;
-
-/**
- * @author Eugene Zhuravlev
- * Date: Feb 9, 2005
- */
-public abstract class NodeRendererImpl extends RendererImpl implements NodeRenderer{
- private String myName;
-
- protected NodeRendererImpl(RendererProvider rendererProvider, String uniqueId) {
- super(rendererProvider, uniqueId);
- }
-
- public final String getName() {
- return myName;
- }
-
- public final void setName(String text) {
- myName = text;
- }
-
- public void readExternal(Element element) throws InvalidDataException {
- super.readExternal(element);
- myName = JDOMExternalizerUtil.readField(element, "NAME");
- }
-
- public void writeExternal(Element element) throws WriteExternalException {
- super.writeExternal(element);
- JDOMExternalizerUtil.writeField(element, "NAME", myName);
- }
-}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java b/openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java
deleted file mode 100644
index 98a5e4347722..000000000000
--- a/openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package com.intellij.debugger.ui.tree.render;
-
-import com.intellij.debugger.engine.DebuggerUtils;
-import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.JDOMExternalizerUtil;
-import com.intellij.openapi.util.WriteExternalException;
-import com.sun.jdi.ReferenceType;
-import com.sun.jdi.Type;
-import org.jdom.Element;
-
-public abstract class ReferenceRenderer extends RendererImpl {
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ReferenceRenderer");
- private String myClassName; // todo: remove from here, use support from RendererImpl
-
- protected ReferenceRenderer(final RendererProvider rendererProvider, final String uniqueId) {
- this("java.lang.Object", rendererProvider, uniqueId);
- }
-
- protected ReferenceRenderer(String className, final RendererProvider rendererProvider, final String uniqueId) {
- super(rendererProvider, uniqueId);
- LOG.assertTrue(className != null);
- myClassName = className;
- }
-
- public String getClassName() {
- return myClassName;
- }
-
- public void setClassName(String className) {
- myClassName = className;
- }
-
- public boolean isApplicable(Type type) {
- if(type == null || !(type instanceof ReferenceType)) {
- return false;
- }
-
- return DebuggerUtils.instanceOf(type, myClassName);
- }
-
- public void writeExternal(Element element) throws WriteExternalException {
- super.writeExternal(element);
- JDOMExternalizerUtil.writeField(element, "QUALIFIED_NAME", getClassName());
- }
-
- public void readExternal(Element element) throws InvalidDataException {
- super.readExternal(element);
- final String className = JDOMExternalizerUtil.readField(element, "QUALIFIED_NAME");
- if(className != null) {
- setClassName(className);
- }
- }
-}
diff --git a/plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java b/plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java
deleted file mode 100644
index 06ef1e6a00f4..000000000000
--- a/plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.intellij.debugger.tree.actions;
-
-import com.intellij.debugger.tree.CommonRenderers;
-
-/*
- * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
- * Use is subject to license terms.
- */
-
-public class ShowAllAsHex extends ShowAllAs {
-
- public ShowAllAsHex() {
- super(CommonRenderers.getInstance().getHexRenderer());
- }
-
-}
diff --git a/resources/src/componentSets/Debugger.xml b/resources/src/componentSets/Debugger.xml
index 716851d080bd..4b597e61ccaf 100644
--- a/resources/src/componentSets/Debugger.xml
+++ b/resources/src/componentSets/Debugger.xml
@@ -1,19 +1,11 @@
-
- com.intellij.debugger.ui.impl.watch.render.DefaultRendererProvider
-
com.intellij.debugger.engine.DebuggerUtils
com.intellij.debugger.impl.DebuggerUtilsImpl
- com.intellij.debugger.ui.tree.render.NodeRendererSettings
- com.intellij.debugger.settings.NodeRendererSettingsImpl
-
-
- com.intellij.debugger.ui.tree.render.NodeProviderManager
- com.intellij.debugger.settings.NodeProviderManagerImpl
+ com.intellij.debugger.settings.NodeRendererSettings
com.intellij.debugger.settings.ThreadsViewSettings
@@ -58,4 +50,12 @@
com.intellij.debugger.ui.ValueLookupManager
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java b/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java
index ae1131ed2ce2..dfb7b47b3553 100644
--- a/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java
+++ b/source/com/intellij/debugger/actions/AdjustArrayRangeAction.java
@@ -3,7 +3,8 @@ package com.intellij.debugger.actions;
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.impl.watch.render.ArrayRenderer;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
diff --git a/source/com/intellij/debugger/actions/ViewAsGroup.java b/source/com/intellij/debugger/actions/ViewAsGroup.java
index b64504067d02..1bba86e53b6e 100644
--- a/source/com/intellij/debugger/actions/ViewAsGroup.java
+++ b/source/com/intellij/debugger/actions/ViewAsGroup.java
@@ -6,7 +6,7 @@ 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.render.NodeRenderer;
-import com.intellij.debugger.ui.tree.render.NodeRendererSettings;
+import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.diagnostic.Logger;
diff --git a/source/com/intellij/debugger/engine/DebugProcessImpl.java b/source/com/intellij/debugger/engine/DebugProcessImpl.java
index 7b4b09b8d469..6847c01f95df 100644
--- a/source/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/source/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -16,12 +16,19 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
+import com.intellij.debugger.settings.AutoRendererNode;
import com.intellij.debugger.settings.DebuggerSettings;
+import com.intellij.debugger.settings.NodeRendererSettings;
+import com.intellij.debugger.settings.ViewsGeneralSettings;
import com.intellij.debugger.ui.DebuggerSmoothManager;
import com.intellij.debugger.ui.DescriptorHistoryManagerImpl;
import com.intellij.debugger.ui.breakpoints.LineBreakpoint;
import com.intellij.debugger.ui.impl.watch.DescriptorHistoryManager;
-import com.intellij.debugger.ui.impl.watch.render.NodeRendererManagerImpl;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
+import com.intellij.debugger.ui.tree.render.ClassRenderer;
+import com.intellij.debugger.ui.tree.render.PrimitiveRenderer;
+import com.intellij.debugger.ui.tree.ValueDescriptor;
+import com.intellij.debugger.ui.tree.render.*;
import com.intellij.execution.CantRunException;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.ExecutionResult;
@@ -46,6 +53,7 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.Alarm;
import com.intellij.util.EventDispatcher;
import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.InternalIterator;
import com.sun.jdi.*;
import com.sun.jdi.connect.*;
import com.sun.jdi.request.EventRequest;
@@ -105,7 +113,17 @@ public abstract class DebugProcessImpl implements DebugProcess {
: EventRequest.SUSPEND_EVENT_THREAD;
private final DescriptorHistoryManager myDescriptorHistoryManager;
- private final NodeRendererManagerImpl myNodeRendererManager = new NodeRendererManagerImpl(this);
+
+ private final List myRenderers = new ArrayList();
+ private final Map myNodeRederersMap = new com.intellij.util.containers.HashMap();
+ private final NodeRendererSettingsListener mySettingsListener = new NodeRendererSettingsListener() {
+ public void renderersChanged() {
+ myNodeRederersMap.clear();
+ myRenderers.clear();
+ loadRenderers();
+ }
+ };
+
private final SuspendManagerImpl mySuspendManager = new SuspendManagerImpl(this);
protected CompoundPositionManager myPositionManager = null;
DebuggerManagerThreadImpl myDebuggerManagerThread;
@@ -120,8 +138,70 @@ public abstract class DebugProcessImpl implements DebugProcess {
myRequestManager = new RequestManagerImpl(this);
myDescriptorHistoryManager = new DescriptorHistoryManagerImpl(project);
setSuspendPolicy(DebuggerSettings.getInstance().isSuspendAllThreads());
+ NodeRendererSettings.getInstance().addListener(mySettingsListener);
+ loadRenderers();
}
+ private void loadRenderers() {
+ getManagerThread().invoke(new DebuggerCommandImpl() {
+ protected void action() throws Exception {
+ if(ViewsGeneralSettings.getInstance().USE_ALTERNATIVE_RENDERERS) {
+ final NodeRendererSettings settings = ((NodeRendererSettings) NodeRendererSettings.getInstance());
+ settings.iterateRenderers(new InternalIterator() {
+ public boolean visit(AutoRendererNode rendererNode) {
+ if(rendererNode.getRenderer() instanceof ValueLabelRenderer) {
+ myRenderers.add(rendererNode);
+ }
+ return true;
+ }
+ });
+ }
+ }
+ });
+ }
+
+ public NodeRenderer getAutoRenderer(ValueDescriptor descriptor) {
+ DebuggerManagerThreadImpl.assertIsManagerThread();
+ final Value value = descriptor.getValue();
+ Type type = value != null ? value.type() : null;
+
+ NodeRenderer renderer = myNodeRederersMap.get(type);
+ if(renderer == null) {
+ for (Iterator iterator = myRenderers.iterator(); iterator.hasNext();) {
+ final AutoRendererNode nodeAutoRenderer = iterator.next();
+ if(nodeAutoRenderer.isApplicable(type, false)) {
+ renderer = nodeAutoRenderer.getRenderer();
+ break;
+ }
+ }
+ if (renderer == null) {
+ renderer = getDefaultRenderer(type);
+ }
+ myNodeRederersMap.put(type, renderer);
+ }
+
+ return renderer;
+ }
+
+ public NodeRenderer getDefaultRenderer(Type type) {
+ final NodeRendererSettings settings = NodeRendererSettings.getInstance();
+
+ final PrimitiveRenderer primitiveRenderer = (PrimitiveRenderer)settings.getPrimitiveRenderer();
+ if(primitiveRenderer.isApplicable(type)) {
+ return primitiveRenderer;
+ }
+
+ final ArrayRenderer arrayRenderer = (ArrayRenderer)settings.getArrayRenderer();
+ if(arrayRenderer.isApplicable(type)) {
+ return arrayRenderer;
+ }
+
+ final ClassRenderer classRenderer = (ClassRenderer)settings.getClassRenderer();
+ LOG.assertTrue(classRenderer.isApplicable(type), type.name());
+ return classRenderer;
+ }
+
+
protected void commitVM(VirtualMachine vm) {
LOG.assertTrue(myState == STATE_INITIAL, "State is invalid " + myState);
DebuggerManagerThreadImpl.assertIsManagerThread();
@@ -647,14 +727,14 @@ public abstract class DebugProcessImpl implements DebugProcess {
}
}
else if (e instanceof CantRunException) {
- message = "Error Launching Debuggee.\n" + ((CantRunException)e).getMessage();
+ message = "Error Launching Debuggee.\n" + e.getMessage();
}
else if (e instanceof VMDisconnectedException) {
message = "VM Disconnected.\n" + "Target virtual machine closed connection.";
}
else if (e instanceof UnknownHostException) {
message = "Cannot Connect to Remote Process.\n" +
- "Host unknown: " + ((UnknownHostException)e).getMessage();
+ "Host unknown: " + e.getMessage();
}
else if (e instanceof IOException) {
IOException e1 = (IOException)e;
@@ -671,24 +751,19 @@ public abstract class DebugProcessImpl implements DebugProcess {
message = buf.toString();
}
else if (e instanceof ExecutionException) {
- message = ((ExecutionException)e).getMessage();
+ message = e.getMessage();
}
else {
- Exception e1 = (Exception)e;
message = "Error Connecting to Remote Process.\n" +
- "Exception occured: " + e1.getClass().getName() + "\n" +
- "Exception message: " + e1.getMessage();
+ "Exception occured: " + e.getClass().getName() + "\n" +
+ "Exception message: " + e.getMessage();
if (LOG.isDebugEnabled()) {
- LOG.debug(e1);
+ LOG.debug(e);
}
}
return message;
}
- public NodeRendererManagerImpl getNodeRendererManager() {
- return myNodeRendererManager;
- }
-
public DescriptorHistoryManager getDescriptorHistoryManager() {
return myDescriptorHistoryManager;
}
@@ -715,7 +790,7 @@ public abstract class DebugProcessImpl implements DebugProcess {
public void dispose() {
LOG.assertTrue(!isAttached());
- myNodeRendererManager.dispose();
+ NodeRendererSettings.getInstance().addListener(mySettingsListener);
myDescriptorHistoryManager.dispose();
}
diff --git a/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java b/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java
index bba82ca735fa..2eca8d2e1c96 100644
--- a/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java
+++ b/source/com/intellij/debugger/settings/ArrayRendererConfigurable.java
@@ -1,8 +1,6 @@
package com.intellij.debugger.settings;
-import com.intellij.debugger.impl.DebuggerUtilsEx;
-import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer;
-import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
@@ -31,19 +29,24 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{
public ArrayRendererConfigurable(ArrayRenderer renderer) {
myRenderer = renderer;
- myFirstIndexLabel .setLabelFor(myFirstIndex);
- myLastIndexLabel .setLabelFor(myLastIndexLabel);
+ myFirstIndexLabel.setLabelFor(myFirstIndex);
+ myLastIndexLabel.setLabelFor(myLastIndexLabel);
myEntriesLimitLabel.setLabelFor(myEntriesLimit);
- DocumentListener listener = new DocumentListener() {
- private void updateEntriesLimit() {
- myEntriesLimit.setText(String.valueOf(getInt(myEndIndex) - getInt(myFirstIndex) + 1));
- }
-
- public void changedUpdate(DocumentEvent e) { updateEntriesLimit(); }
- public void insertUpdate (DocumentEvent e) { updateEntriesLimit(); }
- public void removeUpdate (DocumentEvent e) { updateEntriesLimit(); }
- };
+ final DocumentListener listener = new DocumentListener() {
+ private void updateEntriesLimit() {
+ myEntriesLimit.setText(String.valueOf(getInt(myEndIndex) - getInt(myFirstIndex) + 1));
+ }
+ public void changedUpdate(DocumentEvent e) {
+ updateEntriesLimit();
+ }
+ public void insertUpdate (DocumentEvent e) {
+ updateEntriesLimit();
+ }
+ public void removeUpdate (DocumentEvent e) {
+ updateEntriesLimit();
+ }
+ };
myFirstIndex.getDocument().addDocumentListener(listener);
myEndIndex.getDocument().addDocumentListener(listener);
}
@@ -53,8 +56,8 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{
}
public void reset() {
- myFirstIndex .setText(String.valueOf(myRenderer.START_INDEX));
- myEndIndex .setText(String.valueOf(myRenderer.END_INDEX));
+ myFirstIndex.setText(String.valueOf(myRenderer.START_INDEX));
+ myEndIndex.setText(String.valueOf(myRenderer.END_INDEX));
myEntriesLimit.setText(String.valueOf(myRenderer.ENTRIES_LIMIT));
}
@@ -64,8 +67,8 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{
private void applyTo(ArrayRenderer renderer) {
int newStartIndex = getInt(myFirstIndex);
- int newEndIndex = getInt(myEndIndex);
- int newLimit = getInt(myEntriesLimit);
+ int newEndIndex = getInt(myEndIndex);
+ int newLimit = getInt(myEntriesLimit);
if (newStartIndex >= 0 && newEndIndex >= 0) {
if (newStartIndex >= newEndIndex) {
@@ -103,7 +106,11 @@ public class ArrayRendererConfigurable implements UnnamedConfigurable{
public boolean isModified() {
ArrayRenderer cloneRenderer = myRenderer.clone();
applyTo(cloneRenderer);
- return !DebuggerUtilsEx.externalizableEqual(myRenderer, cloneRenderer);
+ final boolean valuesEqual =
+ (myRenderer.END_INDEX == cloneRenderer.END_INDEX) &&
+ (myRenderer.START_INDEX == cloneRenderer.START_INDEX) &&
+ (myRenderer.ENTRIES_LIMIT == cloneRenderer.ENTRIES_LIMIT);
+ return !valuesEqual;
}
public void disposeUIResources() {
diff --git a/source/com/intellij/debugger/settings/NodeRendererSettings.java b/source/com/intellij/debugger/settings/NodeRendererSettings.java
new file mode 100644
index 000000000000..0924c8c681bf
--- /dev/null
+++ b/source/com/intellij/debugger/settings/NodeRendererSettings.java
@@ -0,0 +1,198 @@
+package com.intellij.debugger.settings;
+
+import com.intellij.debugger.impl.DebuggerUtilsEx;
+import com.intellij.debugger.ui.tree.render.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.NamedJDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.util.EventDispatcher;
+import com.intellij.util.containers.InternalIterator;
+import org.jdom.Element;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * User: lex
+ * Date: Sep 18, 2003
+ * Time: 8:00:25 PM
+ */
+public class NodeRendererSettings implements ApplicationComponent, NamedJDOMExternalizable {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.NodeRendererSettings");
+ private static final String REFERENCE_RENDERER = "Reference renderer";
+ public static final String RENDERER_TAG = "Renderer";
+ private static final String RENDERER_ID = "ID";
+
+ private final EventDispatcher myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class);
+ private RendererConfiguration myRendererConfiguration = new RendererConfiguration(this);
+
+ // default singleton renderers
+ private final PrimitiveRenderer myPrimitiveRenderer = new PrimitiveRenderer();
+ private final ArrayRenderer myArrayRenderer = new ArrayRenderer();
+ private final ClassRenderer myClassRenderer = new ClassRenderer();
+ private final HexRenderer myHexRenderer = new HexRenderer();
+
+
+ public static NodeRendererSettings getInstance() {
+ return ApplicationManager.getApplication().getComponent(NodeRendererSettings.class);
+ }
+
+ public String getComponentName() {
+ return "NodeRendererSettings";
+ }
+
+ public void initComponent() { }
+
+ public void disposeComponent() {
+ }
+
+ public String getExternalFileName() {
+ return "debugger.renderers";
+ }
+
+ public boolean equals(Object o) {
+ if(!(o instanceof NodeRendererSettings)) return false;
+
+ return DebuggerUtilsEx.externalizableEqual(this, (NodeRendererSettings)o);
+ }
+
+ public void addListener(NodeRendererSettingsListener listener) {
+ myDispatcher.addListener(listener);
+ }
+
+ public void removeListener(NodeRendererSettingsListener listener) {
+ myDispatcher.removeListener(listener);
+ }
+
+ public void writeExternal(final Element element) throws WriteExternalException {
+ myRendererConfiguration.writeExternal(element);
+ }
+
+ public void readExternal(final Element root) {
+ myRendererConfiguration.readExternal(root);
+ myDispatcher.getMulticaster().renderersChanged();
+ }
+
+ public RendererConfiguration getRendererConfiguration() {
+ return myRendererConfiguration;
+ }
+
+ public void setRendererConfiguration(final RendererConfiguration rendererConfiguration) {
+ LOG.assertTrue(rendererConfiguration != null);
+ RendererConfiguration oldConfig = myRendererConfiguration;
+ myRendererConfiguration = rendererConfiguration;
+ if (oldConfig == null || !oldConfig.equals(rendererConfiguration)) {
+ fireRenderersChanged();
+ }
+ }
+
+ public void iterateRenderers(InternalIterator iterator) {
+ myRendererConfiguration.iterateRenderers(iterator);
+ }
+
+ public PrimitiveRenderer getPrimitiveRenderer() {
+ return myPrimitiveRenderer;
+ }
+
+ public ArrayRenderer getArrayRenderer() {
+ return myArrayRenderer;
+ }
+
+ public ClassRenderer getClassRenderer() {
+ return myClassRenderer;
+ }
+
+ public HexRenderer getHexRenderer() {
+ return myHexRenderer;
+ }
+
+ public void fireRenderersChanged() {
+ myDispatcher.getMulticaster().renderersChanged();
+ }
+
+ public List getAllRenderers() {
+ final List allRenderers = new ArrayList();
+ myRendererConfiguration.iterateRenderers(new InternalIterator() {
+ public boolean visit(final AutoRendererNode element) {
+ allRenderers.add(element.getRenderer());
+ return true;
+ }
+ });
+ allRenderers.add(myArrayRenderer);
+ allRenderers.add(myClassRenderer);
+ allRenderers.add(myPrimitiveRenderer);
+ allRenderers.add(myHexRenderer);
+ return allRenderers;
+ }
+
+ public boolean isDefault(final Renderer renderer) {
+ return renderer == myPrimitiveRenderer || renderer == myArrayRenderer || renderer == myClassRenderer;
+ }
+
+ public Renderer readRenderer(Element root) throws InvalidDataException {
+ if (root == null) {
+ return null;
+ }
+
+ if (!RENDERER_TAG.equals(root.getName())) {
+ throw new InvalidDataException("Cannot read renderer - tag name is not '" + RENDERER_TAG + "'");
+ }
+
+ final String rendererId = root.getAttributeValue(RENDERER_ID);
+ if(rendererId == null) {
+ throw new InvalidDataException("unknown renderer ID: " + rendererId);
+ }
+
+ final Renderer renderer = createRenderer(rendererId);
+ if(renderer == null) {
+ throw new InvalidDataException("unknown renderer ID: " + rendererId);
+ }
+
+ renderer.readExternal(root);
+
+ return renderer;
+ }
+
+ public Element writeRenderer(Renderer renderer) throws WriteExternalException {
+ Element root = new Element(RENDERER_TAG);
+ if(renderer != null) {
+ root.setAttribute(RENDERER_ID , renderer.getUniqueId());
+ renderer.writeExternal(root);
+ }
+ return root;
+ }
+
+ public Renderer createRenderer(final String rendererId) {
+ if (ClassRenderer.UNIQUE_ID.equals(rendererId)) {
+ return myClassRenderer;
+ }
+ else if (ArrayRenderer.UNIQUE_ID.equals(rendererId)) {
+ return myArrayRenderer;
+ }
+ else if (PrimitiveRenderer.UNIQUE_ID.equals(rendererId)) {
+ return myPrimitiveRenderer;
+ }
+ else if(HexRenderer.UNIQUE_ID.equals(rendererId)) {
+ return myHexRenderer;
+ }
+ else if(rendererId.equals(ExpressionChildrenRenderer.UNIQUE_ID)) {
+ return new ExpressionChildrenRenderer();
+ }
+ else if(rendererId.equals(LabelRenderer.UNIQUE_ID)) {
+ return new LabelRenderer();
+ }
+ else if(rendererId.equals(EnumerationChildrenRenderer.UNIQUE_ID)) {
+ return new EnumerationChildrenRenderer();
+ }
+ else if(rendererId.equals(ToStringRenderer.UNIQUE_ID)) {
+ return new ToStringRenderer();
+ }
+ else if(rendererId.equals(CompoundNodeRenderer.UNIQUE_ID) || rendererId.equals(REFERENCE_RENDERER)) {
+ return new CompoundReferenceRenderer(this, "unnamed", null, null);
+ }
+ return null;
+ }
+}
diff --git a/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java b/source/com/intellij/debugger/settings/RendererConfiguration.java
similarity index 51%
rename from source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java
rename to source/com/intellij/debugger/settings/RendererConfiguration.java
index dcbfaeb0f564..d9b9649af6fc 100644
--- a/source/com/intellij/debugger/settings/NodeRendererSettingsImpl.java
+++ b/source/com/intellij/debugger/settings/RendererConfiguration.java
@@ -1,15 +1,11 @@
package com.intellij.debugger.settings;
import com.intellij.debugger.impl.DebuggerUtilsEx;
-import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer;
-import com.intellij.debugger.ui.impl.watch.render.ClassRenderer;
-import com.intellij.debugger.ui.impl.watch.render.DefaultRendererProvider;
-import com.intellij.debugger.ui.impl.watch.render.PrimitiveRenderer;
import com.intellij.debugger.ui.tree.render.*;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.NamedJDOMExternalizable;
+import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
-import com.intellij.util.EventDispatcher;
import com.intellij.util.containers.InternalIterator;
import org.jdom.Element;
@@ -17,42 +13,27 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-/**
- * User: lex
- * Date: Sep 18, 2003
- * Time: 8:00:25 PM
- */
-public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cloneable, NamedJDOMExternalizable {
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.NodeRendererSettingsImpl");
+public class RendererConfiguration implements Cloneable, JDOMExternalizable {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.NodeRendererSettings");
private static final String AUTO_NODE = "node";
- private static final int VERSION = 3;
+ private static final int VERSION = 5;
- private EventDispatcher myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class);
private List myRepresentationNodes = new ArrayList();
+ private final NodeRendererSettings myRendererSettings;
- public String getComponentName() {
- return "NodeRendererSettings";
+ protected RendererConfiguration(NodeRendererSettings rendererSettings) {
+ myRendererSettings = rendererSettings;
}
- public void initComponent() { }
-
- public void disposeComponent() {
- }
-
- public String getExternalFileName() {
- return "debugger.renderers";
- }
-
- public NodeRendererSettingsImpl clone() {
- NodeRendererSettingsImpl result = null;
+ public RendererConfiguration clone() {
+ RendererConfiguration result = null;
try {
- result = (NodeRendererSettingsImpl)super.clone();
+ result = (RendererConfiguration)super.clone();
}
catch (CloneNotSupportedException e) {
LOG.error(e);
}
- result.myDispatcher = EventDispatcher.create(NodeRendererSettingsListener.class);
result.myRepresentationNodes = new ArrayList();
for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) {
AutoRendererNode autoRendererNode = iterator.next();
@@ -63,17 +44,9 @@ public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cl
}
public boolean equals(Object o) {
- if(!(o instanceof NodeRendererSettingsImpl)) return false;
+ if(!(o instanceof RendererConfiguration)) return false;
- return DebuggerUtilsEx.externalizableEqual(this, (NodeRendererSettingsImpl)o);
- }
-
- public void addListener(NodeRendererSettingsListener listener) {
- myDispatcher.addListener(listener);
- }
-
- public void removeListener(NodeRendererSettingsListener listener) {
- myDispatcher.removeListener(listener);
+ return DebuggerUtilsEx.externalizableEqual(this, (RendererConfiguration)o);
}
public void writeExternal(final Element element) throws WriteExternalException {
@@ -107,13 +80,11 @@ public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cl
for (Iterator iterator = children.iterator(); iterator.hasNext();) {
Element nodeRepresentation = iterator.next();
try {
- addNode(AutoRendererNode.read(nodeRepresentation));
+ addNode(AutoRendererNode.read(nodeRepresentation, myRendererSettings));
} catch (Exception e) {
LOG.debug(e);
}
}
-
- myDispatcher.getMulticaster().renderersChanged();
}
private void addNode(AutoRendererNode nodeRepresentation) {
@@ -129,28 +100,17 @@ public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cl
myRepresentationNodes.remove(renderer);
}
- public List getAllRenderers() {
+ public List getRenderers() {
List result = new ArrayList();
for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) {
AutoRendererNode autoRendererNode = iterator.next();
result.add(autoRendererNode.getRenderer());
}
- final DefaultRendererProvider defaultRendererProvider = DefaultRendererProvider.getInstance();
- result.add(defaultRendererProvider.getArrayRenderer());
- result.add(defaultRendererProvider.getClassRenderer());
- result.add(defaultRendererProvider.getPrimitiveRenderer());
return result;
}
- public boolean isDefault(Renderer renderer) {
- final DefaultRendererProvider defaultRendererProvider = DefaultRendererProvider.getInstance();
- return renderer == defaultRendererProvider.getArrayRenderer() ||
- renderer == defaultRendererProvider.getClassRenderer() ||
- renderer == defaultRendererProvider.getPrimitiveRenderer();
- }
-
public List getAutoNodes() {
List result = new ArrayList();
@@ -164,17 +124,6 @@ public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cl
public void setAutoNodes(List nodes) {
myRepresentationNodes = nodes;
- fireRenderersChanged();
- }
-
- public List getRenderersByProvider(RendererProvider rendererProvider) {
- List result = new ArrayList();
-
- for (Iterator iterator = myRepresentationNodes.iterator(); iterator.hasNext();) {
- AutoRendererNode autoRendererNode = iterator.next();
- if(autoRendererNode.getRenderer().getRendererProvider() == rendererProvider) result.add(autoRendererNode.getRenderer());
- }
- return result;
}
public void iterateRenderers(InternalIterator iterator) {
@@ -183,24 +132,4 @@ public class NodeRendererSettingsImpl extends NodeRendererSettings implements Cl
iterator.visit(autoRendererNode);
}
}
-
- public PrimitiveRenderer getPrimitiveRenderer() {
- return DefaultRendererProvider.getInstance().getPrimitiveRenderer();
- }
-
- public ArrayRenderer getArrayRenderer() {
- return DefaultRendererProvider.getInstance().getArrayRenderer();
- }
-
- public ClassRenderer getClassRenderer() {
- return DefaultRendererProvider.getInstance().getClassRenderer();
- }
-
- public void fireRenderersChanged() {
- myDispatcher.getMulticaster().renderersChanged();
- }
-
- public static NodeRendererSettingsImpl getInstanceEx() {
- return (NodeRendererSettingsImpl)getInstance();
- }
}
diff --git a/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java b/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java
index c568d16e18ac..1f20be79e683 100644
--- a/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java
+++ b/source/com/intellij/debugger/settings/ViewsGeneralConfigurable.java
@@ -1,9 +1,7 @@
package com.intellij.debugger.settings;
-import com.intellij.debugger.ui.impl.watch.render.ClassRenderer;
-import com.intellij.debugger.impl.DebuggerUtilsEx;
+import com.intellij.debugger.ui.tree.render.ClassRenderer;
import com.intellij.openapi.options.Configurable;
-import com.intellij.openapi.util.Comparing;
import com.intellij.ui.StateRestoringCheckBox;
import javax.swing.*;
@@ -15,7 +13,6 @@ import java.awt.*;
* @author Eugene Belyaev
*/
public class ViewsGeneralConfigurable implements Configurable {
- private ViewsGeneralSettings myGeneralSettings;
private JPanel myPanel;
private JCheckBox myAutoscrollCheckBox;
private JCheckBox myShowSyntheticsCheckBox;
@@ -29,7 +26,6 @@ public class ViewsGeneralConfigurable implements Configurable {
private JCheckBox myAlternativeViews;
public ViewsGeneralConfigurable() {
- myGeneralSettings = ViewsGeneralSettings.getInstance();
myShowStaticCheckBox.addChangeListener(new ChangeListener(){
public void stateChanged(ChangeEvent e) {
if(myShowStaticCheckBox.isSelected()) {
@@ -40,7 +36,7 @@ public class ViewsGeneralConfigurable implements Configurable {
}
});
- myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettingsImpl.getInstanceEx().getArrayRenderer());
+ myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer());
myArrayConfigurablePlace.setLayout(new BorderLayout());
myArrayConfigurablePlace.add(myArrayRendererConfigurable.createComponent());
}
@@ -63,27 +59,25 @@ public class ViewsGeneralConfigurable implements Configurable {
public void apply() {
if (myPanel != null) {
- ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance();
+ final boolean renderersWereModified = areDefaultRenderersModified();
+
+ final ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance();
+ generalSettings.AUTOSCROLL_TO_NEW_LOCALS = myAutoscrollCheckBox.isSelected();
+ generalSettings.USE_ALTERNATIVE_RENDERERS = myAlternativeViews.isSelected();
+ generalSettings.HIDE_NULL_ARRAY_ELEMENTS = myHideNullElementsCheckBox.isSelected();
- applyTo(generalSettings);
+ final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
+ classRenderer.SORT_ASCENDING = mySortCheckBox.isSelected();
+ classRenderer.SHOW_STATIC = myShowStaticCheckBox.isSelected();
+ classRenderer.SHOW_STATIC_FINAL = myShowStaticFinalCheckBox.isSelectedWhenSelectable();
+ classRenderer.SHOW_SYNTHETICS = myShowSyntheticsCheckBox.isSelected();
myArrayRendererConfigurable.apply();
- generalSettings.fireRendererSettingsChanged();
- }
- }
-
- private void applyTo(ViewsGeneralSettings generalSettings) {
- generalSettings.AUTOSCROLL_TO_NEW_LOCALS = myAutoscrollCheckBox.isSelected();
- generalSettings.USE_ALTERNATIVE_RENDERERS = myAlternativeViews.isSelected();
- generalSettings.HIDE_NULL_ARRAY_ELEMENTS = myHideNullElementsCheckBox.isSelected();
-
- ClassRenderer classRenderer = (ClassRenderer)NodeRendererSettingsImpl.getInstance().getClassRenderer();
-
- classRenderer.SORT_ASCENDING = mySortCheckBox.isSelected();
- classRenderer.SHOW_STATIC = myShowStaticCheckBox.isSelected();
- classRenderer.SHOW_STATIC_FINAL = myShowStaticFinalCheckBox.isSelectedWhenSelectable();
- classRenderer.SHOW_SYNTHETICS = myShowSyntheticsCheckBox.isSelected();
+ if (renderersWereModified) {
+ NodeRendererSettings.getInstance().fireRenderersChanged();
+ }
+ }
}
public void reset() {
@@ -93,7 +87,7 @@ public class ViewsGeneralConfigurable implements Configurable {
myHideNullElementsCheckBox.setSelected(generalSettings.HIDE_NULL_ARRAY_ELEMENTS);
myAlternativeViews.setSelected(generalSettings.USE_ALTERNATIVE_RENDERERS);
- ClassRenderer classRenderer = (ClassRenderer)NodeRendererSettingsImpl.getInstance().getClassRenderer();
+ ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
myShowSyntheticsCheckBox.setSelected(classRenderer.SHOW_SYNTHETICS);
mySortCheckBox.setSelected(classRenderer.SORT_ASCENDING);
@@ -107,10 +101,27 @@ public class ViewsGeneralConfigurable implements Configurable {
}
public boolean isModified() {
- ViewsGeneralSettings settings = ((ViewsGeneralSettings)ViewsGeneralSettings.getInstance()).clone();
- applyTo(settings);
+ return areGeneralSettingsModified() || areDefaultRenderersModified();
+ }
- return !DebuggerUtilsEx.externalizableEqual(settings, ViewsGeneralSettings.getInstance()) || myArrayRendererConfigurable.isModified();
+ private boolean areGeneralSettingsModified() {
+ ViewsGeneralSettings generalSettings = ViewsGeneralSettings.getInstance();
+ return
+ (generalSettings.AUTOSCROLL_TO_NEW_LOCALS != myAutoscrollCheckBox.isSelected()) ||
+ (generalSettings.USE_ALTERNATIVE_RENDERERS != myAlternativeViews.isSelected()) ||
+ (generalSettings.HIDE_NULL_ARRAY_ELEMENTS != myHideNullElementsCheckBox.isSelected());
+ }
+
+ private boolean areDefaultRenderersModified() {
+ if (myArrayRendererConfigurable.isModified()) {
+ return true;
+ }
+ final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer();
+ return
+ (classRenderer.SORT_ASCENDING != mySortCheckBox.isSelected()) ||
+ (classRenderer.SHOW_STATIC != myShowStaticCheckBox.isSelected()) ||
+ (classRenderer.SHOW_STATIC_FINAL != myShowStaticFinalCheckBox.isSelectedWhenSelectable()) ||
+ (classRenderer.SHOW_SYNTHETICS != myShowSyntheticsCheckBox.isSelected());
}
public String getHelpTopic() {
diff --git a/source/com/intellij/debugger/settings/ViewsGeneralSettings.java b/source/com/intellij/debugger/settings/ViewsGeneralSettings.java
index 987dd5b4d323..eb67adf6f42b 100644
--- a/source/com/intellij/debugger/settings/ViewsGeneralSettings.java
+++ b/source/com/intellij/debugger/settings/ViewsGeneralSettings.java
@@ -1,6 +1,5 @@
package com.intellij.debugger.settings;
-import com.intellij.debugger.ui.tree.render.NodeRendererSettings;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ApplicationComponent;
import com.intellij.openapi.diagnostic.Logger;
@@ -10,7 +9,7 @@ import com.intellij.openapi.util.NamedJDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
-public class ViewsGeneralSettings implements NamedJDOMExternalizable, ApplicationComponent, Cloneable {
+public class ViewsGeneralSettings implements NamedJDOMExternalizable, ApplicationComponent{
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.settings.ViewsSettings");
public boolean SHOW_OBJECTID = true;
public boolean HIDE_NULL_ARRAY_ELEMENTS = true;
@@ -37,7 +36,6 @@ public class ViewsGeneralSettings implements NamedJDOMExternalizable, Applicatio
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
- fireRendererSettingsChanged();
}
public void writeExternal(Element element) throws WriteExternalException {
@@ -49,7 +47,7 @@ public class ViewsGeneralSettings implements NamedJDOMExternalizable, Applicatio
}
void fireRendererSettingsChanged() {
- ((NodeRendererSettingsImpl) myNodeRendererSettings).fireRenderersChanged();
+ myNodeRendererSettings.fireRenderersChanged();
}
public boolean equals(Object object) {
@@ -60,21 +58,4 @@ public class ViewsGeneralSettings implements NamedJDOMExternalizable, Applicatio
AUTOSCROLL_TO_NEW_LOCALS == generalSettings.AUTOSCROLL_TO_NEW_LOCALS;
}
- protected ViewsGeneralSettings clone() {
- try {
- Element root = new Element("root");
- writeExternal(root);
- ViewsGeneralSettings settings = new ViewsGeneralSettings(((NodeRendererSettingsImpl)myNodeRendererSettings).clone());
- settings.readExternal(root);
- return settings;
- }
- catch (WriteExternalException e) {
- LOG.error(e);
- }
- catch (InvalidDataException e) {
- LOG.error(e);
- }
- return this;
- }
-
}
\ No newline at end of file
diff --git a/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java b/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java
index bf223b2f1fde..795e2708207e 100644
--- a/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java
+++ b/source/com/intellij/debugger/ui/impl/nodes/ArrayIndexHelper.java
@@ -4,7 +4,8 @@
*/
package com.intellij.debugger.ui.impl.nodes;
-import com.intellij.debugger.ui.impl.watch.render.ArrayRenderer;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
+import com.intellij.debugger.ui.tree.render.ArrayRenderer;
import com.intellij.openapi.diagnostic.Logger;
import com.sun.jdi.ArrayReference;
diff --git a/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
index e0deccb772eb..d8f1cdd644ac 100644
--- a/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
+++ b/source/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
@@ -17,13 +17,13 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.settings.ThreadsViewSettings;
+import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.impl.DebuggerTreeBase;
import com.intellij.debugger.ui.impl.tree.TreeBuilder;
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.render.ChildrenBuilder;
-import com.intellij.debugger.ui.tree.render.NodeRendererSettings;
import com.intellij.debugger.ui.tree.render.NodeRendererSettingsListener;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.ui.RunContentDescriptor;
diff --git a/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index 62248a4a4e9f..def34d78d7d1 100644
--- a/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/source/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -192,7 +192,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
return myRenderer;
}
- myAutoRenderer = debugProcess.getNodeRendererManager().getAutoRenderer(this);
+ myAutoRenderer = debugProcess.getAutoRenderer(this);
return myAutoRenderer;
}
diff --git a/plugins/debuggerCommonViews/src/actions/ShowAllAs.java b/source/com/intellij/debugger/ui/tree/actions/ShowAllAs.java
similarity index 98%
rename from plugins/debuggerCommonViews/src/actions/ShowAllAs.java
rename to source/com/intellij/debugger/ui/tree/actions/ShowAllAs.java
index 97e2bccdd469..e363b6088fc9 100644
--- a/plugins/debuggerCommonViews/src/actions/ShowAllAs.java
+++ b/source/com/intellij/debugger/ui/tree/actions/ShowAllAs.java
@@ -1,4 +1,4 @@
-package com.intellij.debugger.tree.actions;
+package com.intellij.debugger.ui.tree.actions;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerUtils;
diff --git a/plugins/debuggerCommonViews/src/actions/ShowAllAsDecimal.java b/source/com/intellij/debugger/ui/tree/actions/ShowAllAsDecimal.java
similarity index 87%
rename from plugins/debuggerCommonViews/src/actions/ShowAllAsDecimal.java
rename to source/com/intellij/debugger/ui/tree/actions/ShowAllAsDecimal.java
index fed27d75878c..4aa392245448 100644
--- a/plugins/debuggerCommonViews/src/actions/ShowAllAsDecimal.java
+++ b/source/com/intellij/debugger/ui/tree/actions/ShowAllAsDecimal.java
@@ -1,4 +1,4 @@
-package com.intellij.debugger.tree.actions;
+package com.intellij.debugger.ui.tree.actions;
import com.intellij.debugger.ui.tree.render.NodeRendererSettings;
diff --git a/source/com/intellij/debugger/ui/tree/actions/ShowAllAsHex.java b/source/com/intellij/debugger/ui/tree/actions/ShowAllAsHex.java
new file mode 100644
index 000000000000..043d672737ce
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/actions/ShowAllAsHex.java
@@ -0,0 +1,20 @@
+package com.intellij.debugger.ui.tree.actions;
+
+import com.intellij.debugger.ui.tree.render.HexRenderer;
+import com.intellij.debugger.ui.tree.render.NodeRenderer;
+import com.intellij.debugger.settings.NodeRendererSettings;
+
+import java.util.List;
+import java.util.Iterator;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class ShowAllAsHex extends ShowAllAs {
+
+ public ShowAllAsHex() {
+ super(NodeRendererSettings.getInstance().getHexRenderer());
+ }
+}
diff --git a/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java b/source/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
similarity index 92%
rename from source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
index 19064c6ddad3..6a528a58e356 100644
--- a/source/com/intellij/debugger/ui/impl/watch/render/ArrayRenderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/ArrayRenderer.java
@@ -1,4 +1,4 @@
-package com.intellij.debugger.ui.impl.watch.render;
+package com.intellij.debugger.ui.tree.render;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
@@ -13,7 +13,6 @@ import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.NodeDescriptorFactory;
import com.intellij.debugger.ui.tree.ValueDescriptor;
-import com.intellij.debugger.ui.tree.render.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
@@ -37,8 +36,8 @@ import java.util.ListIterator;
* Date: Sep 18, 2003
* Time: 3:07:19 PM
*/
-public class ArrayRenderer extends ReferenceRenderer implements NodeRenderer{
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ArrayRenderer");
+public class ArrayRenderer extends NodeRendererImpl{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ArrayRenderer");
public static final String UNIQUE_ID = "ArrayRenderer";
@@ -47,12 +46,24 @@ public class ArrayRenderer extends ReferenceRenderer implements NodeRenderer{
public int ENTRIES_LIMIT = 100;
private final static String MORE_ELEMENTS = "...";
- public ArrayRenderer(RendererProvider provider) {
- super(provider, UNIQUE_ID);
+ public ArrayRenderer() {
+ myProperties.setEnabled(true);
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public boolean isEnabled() {
+ return myProperties.isEnabled();
+ }
+
+ public void setEnabled(boolean enabled) {
+ myProperties.setEnabled(enabled);
}
public String getName() {
- return "Default";
+ return "Array";
}
public void setName(String text) {
@@ -181,14 +192,6 @@ public class ArrayRenderer extends ReferenceRenderer implements NodeRenderer{
}
public boolean isApplicable(Type type) {
- if(type == null || !(type instanceof ArrayType)) {
- return false;
- }
-
- if("[]".equals(getClassName())) {
- return true;
- }
-
- return super.isApplicable(type);
+ return (type instanceof ArrayType);
}
}
diff --git a/source/com/intellij/debugger/ui/tree/render/BasicRendererProperties.java b/source/com/intellij/debugger/ui/tree/render/BasicRendererProperties.java
new file mode 100644
index 000000000000..08254bd95068
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/BasicRendererProperties.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Feb 12, 2005
+ */
+public final class BasicRendererProperties implements Cloneable, JDOMExternalizable{
+ // todo: add class filters here
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.BasicRendererProperties");
+
+ private static final String NAME_OPTION = "NAME";
+ private String myName;
+
+ private static final String ENABLED_OPTION = "ENABLED";
+ private Boolean myEnabled;
+
+ private static final String CLASSNAME_OPTION = "QUALIFIED_NAME";
+ private String myClassName;
+
+ public String getName() {
+ return myName;
+ }
+
+ public void setName(final String name) {
+ myName = name;
+ }
+
+ public boolean isEnabled() {
+ return myEnabled != null? myEnabled.booleanValue() : false;
+ }
+
+ public void setEnabled(final boolean enabled) {
+ myEnabled = enabled? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ public String getClassName() {
+ return myClassName;
+ }
+
+ public void setClassName(final String className) {
+ myClassName = className;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ final List options = element.getChildren("option");
+ myName = null;
+ myEnabled = null;
+ myClassName = null;
+ for (Iterator it = options.iterator(); it.hasNext();) {
+ final Element option = (Element)it.next();
+ final String optionName = option.getAttributeValue("name");
+ if (NAME_OPTION.equals(optionName)) {
+ myName = option.getAttributeValue("value");
+ }
+ else if (ENABLED_OPTION.equals(optionName)) {
+ final String val = option.getAttributeValue("value");
+ myEnabled = "true".equalsIgnoreCase(val)? Boolean.TRUE : Boolean.FALSE;
+ }
+ else if (CLASSNAME_OPTION.equals(optionName)) {
+ myClassName = option.getAttributeValue("value");
+ }
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ if (myName != null) {
+ addOption(element, NAME_OPTION, myName);
+ }
+ if (myEnabled != null) {
+ addOption(element, ENABLED_OPTION, myEnabled.booleanValue()? "true" : "false");
+ }
+ if (myClassName != null) {
+ addOption(element, CLASSNAME_OPTION, myClassName);
+ }
+ }
+
+ private void addOption(final Element element, final String optionName, final String optionValue) {
+ final Element option = new Element("option");
+ element.addContent(option);
+ option.setAttribute("name", optionName);
+ option.setAttribute("value", optionValue);
+ }
+
+ public BasicRendererProperties clone() {
+ try {
+ return (BasicRendererProperties)super.clone();
+ }
+ catch (CloneNotSupportedException e) {
+ LOG.error(e);
+ }
+ return null;
+ }
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/BatchEvaluator.java b/source/com/intellij/debugger/ui/tree/render/BatchEvaluator.java
new file mode 100644
index 000000000000..06064ba1139f
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/BatchEvaluator.java
@@ -0,0 +1,199 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.DebuggerManager;
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.debugger.engine.DebugProcessAdapter;
+import com.intellij.debugger.engine.SuspendContext;
+import com.intellij.debugger.engine.managerThread.SuspendContextCommand;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.jdi.ThreadReferenceProxy;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Key;
+import com.intellij.rt.debugger.BatchEvaluatorServer;
+import com.intellij.util.containers.HashMap;
+import com.sun.jdi.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * User: lex
+ * Date: Jul 7, 2003
+ * Time: 11:13:52 PM
+ */
+
+public class BatchEvaluator {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.BatchEvaluator");
+
+ private final DebugProcess myDebugProcess;
+ private boolean myBatchEvaluatorChecked;
+ private ObjectReference myBatchEvaluatorObject;
+ private Method myBatchEvaluatorMethod;
+
+ private static final Key BATCH_EVALUATOR_KEY = new Key("BatchEvaluator");
+ private final HashMap> myBuffer = new HashMap>();
+
+ private BatchEvaluator(DebugProcess process) {
+ myDebugProcess = process;
+ myDebugProcess.addDebugProcessListener(new DebugProcessAdapter() {
+ public void processDetached(DebugProcess process) {
+ myBatchEvaluatorChecked = false;
+ myBatchEvaluatorObject= null;
+ myBatchEvaluatorMethod = null;
+ }
+ });
+ }
+
+ public boolean hasBatchEvaluator(EvaluationContext evaluationContext) {
+ if (!myBatchEvaluatorChecked) {
+ myBatchEvaluatorChecked = true;
+
+ ThreadReferenceProxy thread = evaluationContext.getSuspendContext().getThread();
+
+ if (thread == null) {
+ return false;
+ }
+
+ ThreadReference threadReference = thread.getThreadReference();
+ if(threadReference == null) {
+ return false;
+ }
+
+ ClassType batchEvaluatorClass = null;
+ try {
+ batchEvaluatorClass = (ClassType)myDebugProcess.findClass(evaluationContext, BatchEvaluatorServer.class.getName(),
+ evaluationContext.getClassLoader());
+ }
+ catch (EvaluateException e) {
+ }
+
+ if (batchEvaluatorClass != null) {
+ Method constructor = batchEvaluatorClass.concreteMethodByName("", "()V");
+ if(constructor != null){
+ ObjectReference evaluator = null;
+ try {
+ evaluator = myDebugProcess.newInstance(evaluationContext, batchEvaluatorClass, constructor, new ArrayList());
+ }
+ catch (Exception e) {
+ LOG.debug(e);
+ }
+ myBatchEvaluatorObject = evaluator;
+
+ if(myBatchEvaluatorObject != null) {
+ myBatchEvaluatorMethod = batchEvaluatorClass.concreteMethodByName("evaluate", "([Ljava/lang/Object;)[Ljava/lang/Object;");
+ }
+ }
+ }
+ }
+
+ return myBatchEvaluatorMethod != null;
+ }
+
+ public void invoke(ToStringCommand command) {
+ LOG.assertTrue(DebuggerManager.getInstance(myDebugProcess.getProject()).isDebuggerManagerThread());
+
+ final EvaluationContext evaluationContext = command.getEvaluationContext();
+ final SuspendContext suspendContext = evaluationContext.getSuspendContext();
+
+ if(!hasBatchEvaluator(evaluationContext)) {
+ myDebugProcess.getManagerThread().invokeCommand(command);
+ }
+ else {
+ List toStringCommands = myBuffer.get(suspendContext);
+ if(toStringCommands == null) {
+ final List commands = new ArrayList();
+ toStringCommands = commands;
+ myBuffer.put(suspendContext, commands);
+
+ myDebugProcess.getManagerThread().invokeCommand(new SuspendContextCommand() {
+ public SuspendContext getSuspendContext() {
+ return suspendContext;
+ }
+
+ public void action() {
+ myBuffer.remove(suspendContext);
+
+ if(!doEvaluateBatch(commands, evaluationContext)) {
+ for (Iterator iterator = commands.iterator(); iterator.hasNext();) {
+ ToStringCommand toStringCommand = iterator.next();
+ toStringCommand.action();
+ }
+ }
+ }
+
+ public void commandCancelled() {
+ myBuffer.remove(suspendContext);
+ }
+ });
+ }
+
+ toStringCommands.add(command);
+ }
+ }
+
+ public static BatchEvaluator getBatchEvaluator(DebugProcess debugProcess) {
+ BatchEvaluator batchEvaluator = debugProcess.getUserData(BATCH_EVALUATOR_KEY);
+
+ if(batchEvaluator == null) {
+ batchEvaluator = new BatchEvaluator(debugProcess);
+ debugProcess.putUserData(BATCH_EVALUATOR_KEY, batchEvaluator);
+ }
+ return batchEvaluator;
+ }
+
+ private boolean doEvaluateBatch(List requests, EvaluationContext evaluationContext) {
+ try {
+ DebugProcess debugProcess = evaluationContext.getDebugProcess();
+ List values = new ArrayList();
+ for (Iterator iterator = requests.iterator(); iterator.hasNext();) {
+ ToStringCommand toStringCommand = iterator.next();
+ values.add(toStringCommand.getValue());
+ }
+
+ ArrayType objectArrayClass = (ArrayType)debugProcess.findClass(
+ evaluationContext,
+ "java.lang.Object[]",
+ evaluationContext.getClassLoader());
+ if (objectArrayClass == null) {
+ return false;
+ }
+
+ ArrayReference argArray = debugProcess.newInstance(objectArrayClass, values.size());
+ argArray.setValues(values);
+ List argList = new ArrayList(1);
+ argList.add(argArray);
+ Value value = debugProcess.invokeMethod(evaluationContext, myBatchEvaluatorObject,
+ myBatchEvaluatorMethod, argList);
+ if (value instanceof ArrayReference) {
+ ArrayReference strings = (ArrayReference)value;
+ int idx = 0;
+ for (Iterator iterator = requests.iterator(); iterator.hasNext(); idx++) {
+ ToStringCommand request = iterator.next();
+ final Value strValue = strings.getValue(idx);
+ if(strValue == null || strValue instanceof StringReference){
+ String str = (strValue == null)? null : ((StringReference)strValue).value();
+ request.evaluationResult(str);
+ } else if(strValue instanceof ObjectReference){
+ request.evaluationError(EvaluateExceptionUtil.createEvaluateException(new InvocationException((ObjectReference)strValue)).getMessage());
+ } else {
+ LOG.assertTrue(false);
+ }
+ request.setEvaluated();
+ }
+ }
+ return true;
+ }
+ catch (ClassNotLoadedException e) {
+ }
+ catch (InvalidTypeException e) {
+ }
+ catch (EvaluateException e) {
+ }
+ return false;
+ }
+
+
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/CachedEvaluator.java b/source/com/intellij/debugger/ui/tree/render/CachedEvaluator.java
new file mode 100644
index 000000000000..e8aef384d4f3
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/CachedEvaluator.java
@@ -0,0 +1,89 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+
+import java.lang.ref.SoftReference;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: lex
+ * Date: Dec 27, 2003
+ * Time: 7:56:13 PM
+ * To change this template use Options | File Templates.
+ */
+public abstract class CachedEvaluator {
+ private static class Cache {
+ protected ExpressionEvaluator myEvaluator;
+ protected EvaluateException myException;
+ protected PsiExpression myPsiChildrenExpression;
+ };
+ SoftReference myCache = new SoftReference(null);
+ private TextWithImports myReferenceExpression = DebuggerUtils.getInstance().createExpressionWithImports("");
+
+ protected abstract String getClassName();
+
+ public TextWithImports getReferenceExpression() {
+ return myReferenceExpression != null ? myReferenceExpression : DebuggerUtils.getInstance().createExpressionWithImports("");
+ }
+
+ public void setReferenceExpression(TextWithImports referenceExpression) {
+ myReferenceExpression = referenceExpression;
+ clear();
+ }
+
+ public void clear() {
+ myCache.clear();
+ }
+
+ protected Cache initEvaluatorAndChildrenExpression(final Project project) {
+ final Cache cache = new Cache();
+ try {
+ final PsiClass contextClass = DebuggerUtils.findClass(getClassName(), project);
+ if(contextClass == null) throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS;
+ cache.myPsiChildrenExpression = null;
+ PsiCodeFragment codeFragment = myReferenceExpression.createCodeFragment(contextClass, project);
+ DebuggerUtils.checkSyntax(codeFragment);
+ cache.myPsiChildrenExpression = ((PsiExpressionCodeFragment)codeFragment).getExpression();
+ cache.myEvaluator = DebuggerUtils.getInstance().getEvaluatorBuilder().build(cache.myPsiChildrenExpression);
+ } catch (EvaluateException e) {
+ cache.myException = e;
+ }
+
+ myCache = new SoftReference(cache);
+ return cache;
+ }
+
+ protected ExpressionEvaluator getEvaluator(final Project project) throws EvaluateException {
+ Cache cache = myCache.get();
+ if(cache == null) {
+ cache = PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Computable() {
+ public Cache compute() {
+ return initEvaluatorAndChildrenExpression(project);
+ }
+ });
+ }
+
+ if(cache.myException != null) {
+ throw cache.myException;
+ }
+
+ return cache.myEvaluator;
+ }
+
+ protected PsiExpression getPsiExpression(final Project project) {
+ Cache cache = myCache.get();
+ if(cache == null) {
+ cache = initEvaluatorAndChildrenExpression(project);
+ }
+
+ return cache.myPsiChildrenExpression;
+ }
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java b/source/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java
rename to source/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java b/source/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java
diff --git a/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java b/source/com/intellij/debugger/ui/tree/render/ClassRenderer.java
similarity index 92%
rename from source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/ClassRenderer.java
index 421c3860164e..3a08154a7cc1 100644
--- a/source/com/intellij/debugger/ui/impl/watch/render/ClassRenderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/ClassRenderer.java
@@ -1,4 +1,4 @@
-package com.intellij.debugger.ui.impl.watch.render;
+package com.intellij.debugger.ui.tree.render;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
@@ -9,7 +9,6 @@ import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.*;
-import com.intellij.debugger.ui.tree.render.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
@@ -31,8 +30,8 @@ import java.util.List;
* Date: Sep 17, 2003
* Time: 2:04:00 PM
*/
-public class ClassRenderer extends ReferenceRenderer implements NodeRenderer{
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ClassRenderer");
+public class ClassRenderer extends NodeRendererImpl{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ClassRenderer");
public static final String UNIQUE_ID = "ClassRenderer";
@@ -42,16 +41,27 @@ public class ClassRenderer extends ReferenceRenderer implements NodeRenderer{
public boolean SHOW_STATIC_FINAL = false;
public boolean CHILDREN_PHYSICAL = true;
- public ClassRenderer(RendererProvider provider) {
- super(provider, UNIQUE_ID);
+ public ClassRenderer() {
+ myProperties.setEnabled(true);
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public boolean isEnabled() {
+ return myProperties.isEnabled();
+ }
+
+ public void setEnabled(boolean enabled) {
+ myProperties.setEnabled(enabled);
}
public ClassRenderer clone() {
return (ClassRenderer) super.clone();
}
- public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener)
- throws EvaluateException {
+ public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) throws EvaluateException {
return calcLabel(descriptor);
}
@@ -181,14 +191,11 @@ public class ClassRenderer extends ReferenceRenderer implements NodeRenderer{
}
public boolean isApplicable(Type type) {
- if(!(type instanceof ReferenceType) || type instanceof ArrayType) {
- return false;
- }
- return super.isApplicable(type);
+ return type instanceof ReferenceType && !(type instanceof ArrayType);
}
public String getName() {
- return "Default";
+ return "Object";
}
public void setName(String text) {
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java b/source/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java
rename to source/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java b/source/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java
similarity index 72%
rename from openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java
index 2a3e3a8e144c..183591b4d10a 100644
--- a/openapi/src/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java
@@ -3,6 +3,7 @@ package com.intellij.debugger.ui.tree.render;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
@@ -25,18 +26,23 @@ public class CompoundNodeRenderer extends NodeRendererImpl{
protected ValueLabelRenderer myLabelRenderer;
protected ChildrenRenderer myChildrenRenderer;
+ private final NodeRendererSettings myRendererSettings;
- public CompoundNodeRenderer(RendererProvider provider, String name, ValueLabelRenderer labelRenderer, ChildrenRenderer childrenRenderer) {
- super(provider, UNIQUE_ID);
+ public CompoundNodeRenderer(NodeRendererSettings rendererSettings, String name, ValueLabelRenderer labelRenderer, ChildrenRenderer childrenRenderer) {
+ myRendererSettings = rendererSettings;
setName(name);
myLabelRenderer = labelRenderer;
myChildrenRenderer = childrenRenderer;
}
- public Renderer clone() {
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public CompoundNodeRenderer clone() {
CompoundNodeRenderer renderer = (CompoundNodeRenderer)super.clone();
- renderer.myLabelRenderer = myLabelRenderer != null ? (ValueLabelRenderer)myLabelRenderer.clone() : null;
- renderer.myChildrenRenderer = myChildrenRenderer != null ? (ChildrenRenderer)myChildrenRenderer.clone() : null;
+ renderer.myLabelRenderer = (myLabelRenderer != null) ? (ValueLabelRenderer)myLabelRenderer.clone() : null;
+ renderer.myChildrenRenderer = (myChildrenRenderer != null) ? (ChildrenRenderer)myChildrenRenderer.clone() : null;
return renderer;
}
@@ -78,19 +84,16 @@ public class CompoundNodeRenderer extends NodeRendererImpl{
public void readExternal(Element element) throws InvalidDataException {
super.readExternal(element);
- if(getName() == null) {
- setName("");
- }
- List children = element.getChildren(NodeRendererExternalizer.RENDERER_TAG);
- myLabelRenderer = (ValueLabelRenderer) NodeRendererExternalizer.readRenderer(children.get(0));
- myChildrenRenderer = (ChildrenRenderer) NodeRendererExternalizer.readRenderer(children.get(1));
+ final List children = element.getChildren(NodeRendererSettings.RENDERER_TAG);
+ myLabelRenderer = (ValueLabelRenderer) myRendererSettings.readRenderer(children.get(0));
+ myChildrenRenderer = (ChildrenRenderer) myRendererSettings.readRenderer(children.get(1));
}
public void writeExternal(Element element) throws WriteExternalException {
super.writeExternal(element);
- final Element labelRendererElement = NodeRendererExternalizer.writeRenderer(myLabelRenderer);
+ final Element labelRendererElement = myRendererSettings.writeRenderer(myLabelRenderer);
element.addContent(labelRendererElement);
- final Element childrenRendererElement = NodeRendererExternalizer.writeRenderer(myChildrenRenderer);
+ final Element childrenRendererElement = myRendererSettings.writeRenderer(myChildrenRenderer);
element.addContent(childrenRendererElement);
}
}
diff --git a/source/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java b/source/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java
new file mode 100644
index 000000000000..82aa75c56f41
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java
@@ -0,0 +1,67 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.settings.NodeRendererSettings;
+import com.intellij.openapi.diagnostic.Logger;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class CompoundReferenceRenderer extends CompoundNodeRenderer{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer");
+
+ public CompoundReferenceRenderer(final NodeRendererSettings rendererSettings, String name, ValueLabelRenderer labelRenderer, ChildrenRenderer childrenRenderer) {
+ super(rendererSettings, name, labelRenderer, childrenRenderer);
+ myProperties.setClassName("java.lang.Object");
+ LOG.assertTrue(labelRenderer == null || labelRenderer instanceof ReferenceRenderer);
+ LOG.assertTrue(childrenRenderer == null || childrenRenderer instanceof ReferenceRenderer);
+ }
+
+ public void setLabelRenderer(ValueLabelRenderer labelRenderer) {
+ super.setLabelRenderer(NodeRendererSettings.getInstance().isDefault(labelRenderer) ? null : labelRenderer);
+ }
+
+ public void setChildrenRenderer(ChildrenRenderer childrenRenderer) {
+ super.setChildrenRenderer(NodeRendererSettings.getInstance().isDefault(childrenRenderer) ? null : childrenRenderer);
+ }
+
+ public ChildrenRenderer getChildrenRenderer() {
+ return super.getChildrenRenderer() != null ? super.getChildrenRenderer() : getDefaultRenderer();
+ }
+
+ private NodeRenderer getDefaultRenderer() {
+ final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance();
+ return getClassName().endsWith("]") ? (NodeRenderer)rendererSettings.getArrayRenderer() : (NodeRenderer)rendererSettings.getClassRenderer();
+ }
+
+ public ValueLabelRenderer getLabelRenderer() {
+ return super.getLabelRenderer() != null ? super.getLabelRenderer() : getDefaultRenderer();
+ }
+
+ private ChildrenRenderer getRawChildrenRenderer() {
+ NodeRenderer classRenderer = getDefaultRenderer();
+ return myChildrenRenderer == classRenderer ? null : myChildrenRenderer;
+ }
+
+ private ValueLabelRenderer getRawLabelRenderer() {
+ NodeRenderer classRenderer = getDefaultRenderer();
+ return myLabelRenderer == classRenderer ? null : myLabelRenderer;
+ }
+
+ public void setClassName(String name) {
+ LOG.assertTrue(name != null);
+ myProperties.setClassName(name);
+ if(getRawLabelRenderer() != null) {
+ ((ReferenceRenderer)myLabelRenderer).setClassName(name);
+ }
+
+ if(getRawChildrenRenderer() != null) {
+ ((ReferenceRenderer)myChildrenRenderer).setClassName(name);
+ }
+ }
+
+ public String getClassName() {
+ return myProperties.getClassName();
+ }
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java b/source/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java
rename to source/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java
diff --git a/source/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java b/source/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java
new file mode 100644
index 000000000000..05e237f52b89
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java
@@ -0,0 +1,105 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.ui.tree.*;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.PsiExpression;
+import com.sun.jdi.Value;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * User: lex
+ * Date: Dec 19, 2003
+ * Time: 1:25:15 PM
+ */
+public final class EnumerationChildrenRenderer extends com.intellij.debugger.ui.tree.render.ReferenceRenderer implements ChildrenRenderer{
+ public static final String UNIQUE_ID = "EnumerationChildrenRenderer";
+
+ private List> myChildren;
+ public static final String CHILDREN_EXPRESSION = "ChildrenExpression";
+ public static final String CHILD_NAME = "Name";
+
+ public EnumerationChildrenRenderer() {
+ this(new ArrayList>());
+ }
+
+ public EnumerationChildrenRenderer(List> children) {
+ super();
+ myChildren = children;
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public EnumerationChildrenRenderer clone() {
+ return (EnumerationChildrenRenderer)super.clone();
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+
+ myChildren.clear();
+
+ List children = element.getChildren(CHILDREN_EXPRESSION);
+ for (Iterator iterator = children.iterator(); iterator.hasNext();) {
+ Element item = iterator.next();
+
+ String name = item.getAttributeValue(CHILD_NAME);
+ TextWithImports text = DebuggerUtils.getInstance().readTextWithImports((Element) item.getChildren().get(0));
+
+ myChildren.add(new Pair(name, text));
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ super.writeExternal(element);
+
+ for (Iterator> iterator = myChildren.iterator(); iterator.hasNext();) {
+ Pair pair = iterator.next();
+ Element child = new Element(CHILDREN_EXPRESSION);
+ child.setAttribute(CHILD_NAME, pair.getFirst());
+ child.addContent(DebuggerUtils.getInstance().writeTextWithImports(pair.getSecond()));
+
+ element.addContent(child);
+ }
+ }
+
+ public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) {
+ NodeManager nodeManager = builder.getNodeManager();
+ NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager();
+
+ List children = new ArrayList();
+ for (Iterator> iterator = myChildren.iterator(); iterator.hasNext();) {
+ Pair pair = iterator.next();
+ children.add(nodeManager.createNode(descriptorFactory.getUserExpressionDescriptor(builder.getParentDescriptor(), getClassName(), pair.getFirst(), pair.getSecond()), evaluationContext));
+ }
+ builder.setChildren(children);
+ }
+
+ public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException {
+ return ((ValueDescriptor) node.getDescriptor()).getDescriptorEvaluation(context);
+ }
+
+ public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) {
+ return myChildren.size() > 0;
+ }
+
+ public List> getChildren() {
+ return myChildren;
+ }
+
+ public void setChildren(List> children) {
+ myChildren = children;
+ }
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java b/source/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java
new file mode 100644
index 000000000000..aed691587a72
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java
@@ -0,0 +1,171 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.DebugProcessImpl;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.debugger.ui.tree.DebuggerTreeNode;
+import com.intellij.debugger.ui.tree.NodeDescriptor;
+import com.intellij.debugger.ui.tree.NodeManager;
+import com.intellij.debugger.ui.tree.ValueDescriptor;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.psi.PsiExpression;
+import com.sun.jdi.BooleanValue;
+import com.sun.jdi.Value;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: lex
+ * Date: Sep 17, 2003
+ * Time: 2:04:00 PM
+ */
+public class ExpressionChildrenRenderer extends ReferenceRenderer implements ChildrenRenderer {
+ public static final String UNIQUE_ID = "ExpressionChildrenRenderer";
+ private static final Key EXPRESSION_VALUE = new Key("EXPRESSION_VALUE");
+
+ private final CachedEvaluator myChildrenExpandable = new CachedEvaluator() {
+ protected String getClassName() {
+ return ExpressionChildrenRenderer.this.getClassName();
+ }
+ };
+
+ private final CachedEvaluator myChildrenExpression = new CachedEvaluator() {
+ protected String getClassName() {
+ return ExpressionChildrenRenderer.this.getClassName();
+ }
+ };
+
+ public ExpressionChildrenRenderer() {
+ super();
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public ExpressionChildrenRenderer clone() {
+ return (ExpressionChildrenRenderer)super.clone();
+ }
+
+ public void buildChildren(final Value value, final ChildrenBuilder builder, final EvaluationContext evaluationContext) {
+ final NodeManager nodeManager = builder.getNodeManager();
+
+ try {
+ final Value childrenValue = evaluateChildren(
+ evaluationContext.createEvaluationContext(value), builder.getParentDescriptor()
+ );
+
+ ChildrenRenderer defaultRenderer = ((DebugProcessImpl)evaluationContext.getDebugProcess()).getDefaultRenderer(childrenValue.type());
+ defaultRenderer.buildChildren(childrenValue, builder, evaluationContext);
+ }
+ catch (final EvaluateException e) {
+ List errorChildren = new ArrayList();
+ errorChildren.add(nodeManager.createMessageNode(e.getMessage() + " Failed to evaluate expression for this object alternative view."));
+ builder.setChildren(errorChildren);
+ }
+ }
+
+ private Value evaluateChildren(EvaluationContext context, NodeDescriptor descriptor) throws EvaluateException {
+ final ExpressionEvaluator evaluator = myChildrenExpression.getEvaluator(context.getDebugProcess().getProject());
+
+ Value value = evaluator.evaluate(context);
+ descriptor.putUserData(EXPRESSION_VALUE, value);
+ return value;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+ DefaultJDOMExternalizer.readExternal(this, element);
+
+ TextWithImports childrenExpression = DebuggerUtils.getInstance().readTextWithImports(element, "CHILDREN_EXPRESSION");
+ if(childrenExpression != null) {
+ setChildrenExpression(childrenExpression);
+ }
+
+ TextWithImports childrenExpandable = DebuggerUtils.getInstance().readTextWithImports(element, "CHILDREN_EXPANDABLE");
+ if(childrenExpandable != null) {
+ myChildrenExpandable.setReferenceExpression(childrenExpandable);
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ super.writeExternal(element);
+ DefaultJDOMExternalizer.writeExternal(this, element);
+ DebuggerUtils.getInstance().writeTextWithImports(element, "CHILDREN_EXPANDABLE", getChildrenExpandable());
+ DebuggerUtils.getInstance().writeTextWithImports(element, "CHILDREN_EXPRESSION", getChildrenExpression());
+ }
+
+ public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException {
+ ValueDescriptor descriptor = (ValueDescriptor) node.getParent().getDescriptor();
+ Value expressionValue = descriptor.getUserData(EXPRESSION_VALUE);
+ if(expressionValue == null) {
+ throw EvaluateExceptionUtil.createEvaluateException("Node is not evaluated - internal error");
+ }
+
+ ChildrenRenderer defaultChildrenRenderer = ((DebugProcessImpl)context.getDebugProcess()).getDefaultRenderer(expressionValue.type());
+
+ return DebuggerUtils.getInstance().substituteThis(
+ defaultChildrenRenderer.getChildValueExpression(node, context),
+ (PsiExpression)myChildrenExpression.getPsiExpression(node.getProject()).copy(),
+ expressionValue, context);
+ }
+
+ public boolean isExpandable(Value value, final EvaluationContext context, NodeDescriptor parentDescriptor) {
+ final EvaluationContext evaluationContext = context.createEvaluationContext(value);
+
+ if(!"".equals(myChildrenExpandable.getReferenceExpression())) {
+ try {
+ Value expanded = myChildrenExpandable.getEvaluator(evaluationContext.getProject()).evaluate(evaluationContext);
+ if(expanded instanceof BooleanValue) {
+ return ((BooleanValue)expanded).booleanValue();
+ }
+ }
+ catch (EvaluateException e) {
+ }
+ }
+
+ try {
+ Value children = evaluateChildren(evaluationContext, parentDescriptor);
+
+ ChildrenRenderer defaultChildrenRenderer = ((DebugProcessImpl)evaluationContext.getDebugProcess()).getDefaultRenderer(value.type());
+
+ return defaultChildrenRenderer.isExpandable(children, evaluationContext, parentDescriptor);
+ }
+ catch (EvaluateException e) {
+ return true;
+ }
+ }
+
+ public TextWithImports getChildrenExpression() {
+ return myChildrenExpression.getReferenceExpression();
+ }
+
+ public void setChildrenExpression(TextWithImports expression) {
+ myChildrenExpression.setReferenceExpression(expression);
+ }
+
+ public TextWithImports getChildrenExpandable() {
+ return myChildrenExpandable.getReferenceExpression();
+ }
+
+ public void setChildrenExpandable(TextWithImports childrenExpandable) {
+ myChildrenExpandable.setReferenceExpression(childrenExpandable);
+ }
+
+ public void setClassName(String name) {
+ super.setClassName(name);
+ myChildrenExpression.clear();
+ myChildrenExpandable.clear();
+ }
+
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/HexRenderer.java b/source/com/intellij/debugger/ui/tree/render/HexRenderer.java
new file mode 100644
index 000000000000..d6e9bcdac81b
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/HexRenderer.java
@@ -0,0 +1,113 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+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.render.ChildrenBuilder;
+import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
+import com.intellij.debugger.ui.tree.render.NodeRendererImpl;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.PsiExpression;
+import com.sun.jdi.*;
+
+/**
+ * User: lex
+ * Date: Nov 19, 2003
+ * Time: 3:13:11 PM
+ */
+public class HexRenderer extends NodeRendererImpl{
+ public static final String UNIQUE_ID = "HexRenderer";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.HexRenderer");
+
+ public HexRenderer() {
+ setEnabled(false);
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public String getName() {
+ return "Hex";
+ }
+
+ public void setName(String name) {
+ // prohibit change
+ }
+
+ public HexRenderer clone() {
+ return (HexRenderer) super.clone();
+ }
+
+ public String calcLabel(ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) {
+ Value value = valueDescriptor.getValue();
+ StringBuffer buf = new StringBuffer(16);
+
+ if(value == null) {
+ buf.append("null");
+ }
+ else if (value instanceof CharValue) {
+ buf.append("'");
+ buf.append(DebuggerUtils.translateStringValue(value.toString()));
+ buf.append("' ");
+ long longValue = ((PrimitiveValue)value).longValue();
+ buf.append("0x" + Long.toHexString(longValue).toUpperCase());
+ }
+ else if (value instanceof ByteValue) {
+ byte val = ((PrimitiveValue)value).byteValue();
+ String strValue = Integer.toHexString(val).toUpperCase();
+ if (strValue.length() > 2) {
+ strValue = strValue.substring(strValue.length() - 2);
+ }
+ buf.append("0x" + strValue);
+ }
+ else if (value instanceof ShortValue) {
+ short val = ((PrimitiveValue)value).shortValue();
+ String strValue = Integer.toHexString(val).toUpperCase();
+ if (strValue.length() > 4) {
+ strValue = strValue.substring(strValue.length() - 4);
+ }
+ buf.append("0x" + strValue);
+ }
+ else if (value instanceof IntegerValue) {
+ int val = ((PrimitiveValue)value).intValue();
+ buf.append("0x" + Integer.toHexString(val).toUpperCase());
+ }
+ else if (value instanceof LongValue) {
+ long val = ((PrimitiveValue)value).longValue();
+ buf.append("0x" + Long.toHexString(val).toUpperCase());
+ }
+ else {
+ LOG.assertTrue(false);
+ }
+ return buf.toString();
+ }
+
+ public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) {
+ }
+
+ //returns whether this renderer is apllicable to this type or it's supertypes
+ public boolean isApplicable(Type t) {
+ if(t == null) {
+ return false;
+ }
+ return t instanceof CharType ||
+ t instanceof ByteType ||
+ t instanceof ShortType ||
+ t instanceof IntegerType ||
+ t instanceof LongType;
+ }
+
+ public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) {
+ LOG.assertTrue(false);
+ return null;
+ }
+
+ public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) {
+ return false;
+ }
+
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/LabelRenderer.java b/source/com/intellij/debugger/ui/tree/render/LabelRenderer.java
new file mode 100644
index 000000000000..b11b2591e3ef
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/LabelRenderer.java
@@ -0,0 +1,97 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.engine.DebugProcess;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
+import com.intellij.debugger.ui.tree.ValueDescriptor;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.sun.jdi.PrimitiveValue;
+import com.sun.jdi.Value;
+import org.jdom.Element;
+
+/**
+ * User: lex
+ * Date: Sep 20, 2003
+ * Time: 10:27:12 PM
+ */
+public class LabelRenderer extends com.intellij.debugger.ui.tree.render.ReferenceRenderer implements ValueLabelRenderer{
+ public static final String UNIQUE_ID = "LabelRenderer";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ClassLabelRenderer");
+
+ private final CachedEvaluator myLabelExpression = new CachedEvaluator() {
+ protected String getClassName() {
+ return LabelRenderer.this.getClassName();
+ }
+ };
+
+ public LabelRenderer() {
+ super();
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public LabelRenderer clone() {
+ return (LabelRenderer)super.clone();
+ }
+
+ public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener)
+ throws EvaluateException {
+ String result;
+ LOG.assertTrue(!(descriptor instanceof PrimitiveValue));
+
+ final DebugProcess debugProcess = evaluationContext.getDebugProcess();
+ final Value value = descriptor.getValue();
+ if (value != null) {
+ try {
+ final ExpressionEvaluator evaluator = myLabelExpression.getEvaluator(debugProcess.getProject());
+
+ if(!debugProcess.isAttached()) {
+ throw EvaluateExceptionUtil.PROCESS_EXITED;
+ }
+ EvaluationContext thisEvaluationContext = evaluationContext.createEvaluationContext(value);
+ Value labelValue = evaluator.evaluate(thisEvaluationContext);
+ result = DebuggerUtils.getValueAsString(thisEvaluationContext, labelValue);
+ }
+ catch (final EvaluateException ex) {
+ throw new EvaluateException(ex.getMessage() + " Failed to evaluate expression for this object alternative view", ex);
+ }
+ }
+ else {
+ result = "null";
+ }
+ return result;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ super.readExternal(element);
+ DefaultJDOMExternalizer.readExternal(this, element);
+ TextWithImports labelExpression = DebuggerUtils.getInstance().readTextWithImports(element, "LABEL_EXPRESSION");
+ if (labelExpression != null) {
+ setLabelExpression(labelExpression);
+ }
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ super.writeExternal(element);
+ DefaultJDOMExternalizer.writeExternal(this, element);
+ DebuggerUtils.getInstance().writeTextWithImports(element, "LABEL_EXPRESSION", getLabelExpression());
+ }
+
+ public TextWithImports getLabelExpression() {
+ return myLabelExpression.getReferenceExpression();
+ }
+
+ public void setLabelExpression(TextWithImports expression) {
+ myLabelExpression.setReferenceExpression(expression);
+ }
+
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/NodeRenderer.java b/source/com/intellij/debugger/ui/tree/render/NodeRenderer.java
similarity index 82%
rename from openapi/src/com/intellij/debugger/ui/tree/render/NodeRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/NodeRenderer.java
index 39234b66c5d8..a95346c42923 100644
--- a/openapi/src/com/intellij/debugger/ui/tree/render/NodeRenderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/NodeRenderer.java
@@ -9,4 +9,8 @@ public interface NodeRenderer extends ChildrenRenderer, ValueLabelRenderer {
String getName();
void setName(String text);
+
+ boolean isEnabled();
+
+ void setEnabled(boolean enabled);
}
diff --git a/source/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java b/source/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java
new file mode 100644
index 000000000000..11c0c96e98d8
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Feb 9, 2005
+ */
+public abstract class NodeRendererImpl implements NodeRenderer{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.NodeRendererImpl");
+ protected BasicRendererProperties myProperties = new BasicRendererProperties();
+
+ protected NodeRendererImpl() {
+ myProperties.setName("unnamed");
+ }
+
+ public String getName() {
+ return myProperties.getName();
+ }
+
+ public void setName(String name) {
+ myProperties.setName(name);
+ }
+
+ public boolean isEnabled() {
+ return myProperties.isEnabled();
+ }
+
+ public void setEnabled(boolean enabled) {
+ myProperties.setEnabled(enabled);
+ }
+
+ public NodeRendererImpl clone() {
+ try {
+ final NodeRendererImpl cloned = (NodeRendererImpl)super.clone();
+ cloned.myProperties = myProperties.clone();
+ return cloned;
+ }
+ catch (CloneNotSupportedException e) {
+ LOG.error(e);
+ }
+ return null;
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ myProperties.readExternal(element);
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ myProperties.writeExternal(element);
+ }
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java b/source/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java
rename to source/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java
diff --git a/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java b/source/com/intellij/debugger/ui/tree/render/PrimitiveRenderer.java
similarity index 75%
rename from source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/PrimitiveRenderer.java
index e44b9987e248..49473c2b1637 100644
--- a/source/com/intellij/debugger/ui/impl/watch/render/PrimitiveRenderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/PrimitiveRenderer.java
@@ -1,22 +1,15 @@
-package com.intellij.debugger.ui.impl.watch.render;
+package com.intellij.debugger.ui.tree.render;
+import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
-import com.intellij.debugger.engine.StackFrameContext;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.impl.DebuggerUtilsEx;
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.render.*;
-import com.intellij.debugger.DebuggerContext;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.DefaultJDOMExternalizer;
-import com.intellij.openapi.util.InvalidDataException;
-import com.intellij.openapi.util.WriteExternalException;
import com.intellij.psi.PsiExpression;
-import com.intellij.util.IncorrectOperationException;
import com.sun.jdi.*;
-import org.jdom.Element;
/**
* User: lex
@@ -25,29 +18,34 @@ import org.jdom.Element;
*/
public class PrimitiveRenderer extends NodeRendererImpl {
public static final String UNIQUE_ID = "PrimitiveRenderer";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.PrimitiveRenderer");
- private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.PrimitiveRenderer");
+ public PrimitiveRenderer() {
+ myProperties.setName("Primitive");
+ }
- public PrimitiveRenderer(final RendererProvider provider) {
- super(provider, UNIQUE_ID);
- setName("Default");
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public String getName() {
+ return "Primitive";
}
- /*
public void setName(String text) {
- LOG.assertTrue(false, "Cannot set name for primitive renderer");
+ // prohibit name change
}
- */
- public PrimitiveRenderer clone(){
- return (PrimitiveRenderer)super.clone();
+ public final boolean isEnabled() {
+ return true;
+ }
+
+ public void setEnabled(boolean enabled) {
+ // prohibit change
}
public boolean isApplicable(Type type) {
- if(type == null) {
- return true;
- }
- return type instanceof PrimitiveType || type instanceof VoidType;
+ return (type == null) || (type instanceof PrimitiveType) || (type instanceof VoidType);
}
public String calcLabel(ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener) {
diff --git a/source/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java b/source/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java
new file mode 100644
index 000000000000..71b623d5f11b
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java
@@ -0,0 +1,59 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.Type;
+import org.jdom.Element;
+
+public abstract class ReferenceRenderer implements Renderer {
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ReferenceRenderer");
+ protected BasicRendererProperties myProperties = new BasicRendererProperties();
+
+ protected ReferenceRenderer() {
+ this("java.lang.Object");
+ }
+
+ protected ReferenceRenderer(String className) {
+ LOG.assertTrue(className != null);
+ myProperties.setClassName(className);
+ }
+
+ public String getClassName() {
+ return myProperties.getClassName();
+ }
+
+ public void setClassName(String className) {
+ myProperties.setClassName(className);
+ }
+
+ public Renderer clone() {
+ final ReferenceRenderer cloned;
+ try {
+ cloned = (ReferenceRenderer)super.clone();
+ cloned.myProperties = myProperties.clone();
+ return cloned;
+ }
+ catch (CloneNotSupportedException e) {
+ LOG.error(e);
+ }
+ return null;
+ }
+
+ public boolean isApplicable(Type type) {
+ if(type == null || !(type instanceof ReferenceType)) {
+ return false;
+ }
+ return DebuggerUtils.instanceOf(type, getClassName());
+ }
+
+ public void writeExternal(Element element) throws WriteExternalException {
+ myProperties.writeExternal(element);
+ }
+
+ public void readExternal(Element element) throws InvalidDataException {
+ myProperties.readExternal(element);
+ }
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/Renderer.java b/source/com/intellij/debugger/ui/tree/render/Renderer.java
similarity index 80%
rename from openapi/src/com/intellij/debugger/ui/tree/render/Renderer.java
rename to source/com/intellij/debugger/ui/tree/render/Renderer.java
index 29bdc3829473..734c3daf999a 100644
--- a/openapi/src/com/intellij/debugger/ui/tree/render/Renderer.java
+++ b/source/com/intellij/debugger/ui/tree/render/Renderer.java
@@ -5,11 +5,6 @@ import com.intellij.openapi.util.JDOMExternalizable;
import com.sun.jdi.Type;
public interface Renderer extends Cloneable, JDOMExternalizable {
- boolean isEnabled();
-
- void setEnabled(boolean enabled);
-
- RendererProvider getRendererProvider();
String getUniqueId();
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/RendererProvider.java b/source/com/intellij/debugger/ui/tree/render/RendererProvider.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/RendererProvider.java
rename to source/com/intellij/debugger/ui/tree/render/RendererProvider.java
diff --git a/source/com/intellij/debugger/ui/tree/render/ToStringCommand.java b/source/com/intellij/debugger/ui/tree/render/ToStringCommand.java
new file mode 100644
index 000000000000..e943cff566f9
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/ToStringCommand.java
@@ -0,0 +1,58 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.SuspendContext;
+import com.intellij.debugger.engine.managerThread.SuspendContextCommand;
+import com.sun.jdi.Value;
+
+/**
+ * User: lex
+ * Date: Sep 16, 2003
+ * Time: 10:58:26 AM
+ */
+public abstract class ToStringCommand implements SuspendContextCommand {
+ private final EvaluationContext myEvaluationContext;
+ private final Value myValue;
+
+ private boolean myIsEvaluated = false;
+
+ protected ToStringCommand(EvaluationContext evaluationContext, Value value) {
+ myEvaluationContext = evaluationContext;
+ myValue = value;
+ }
+
+ public void action() {
+ if(myIsEvaluated) return;
+ try {
+ final String valueAsString = DebuggerUtils.getValueAsString(myEvaluationContext, myValue);
+ evaluationResult(valueAsString);
+ } catch(final EvaluateException ex) {
+ evaluationError(ex.getMessage());
+ }
+ }
+
+ public void commandCancelled() {
+ }
+
+ public void setEvaluated() {
+ myIsEvaluated = true;
+ }
+
+ public SuspendContext getSuspendContext() {
+ return myEvaluationContext.getSuspendContext();
+ }
+
+ public abstract void evaluationResult(String message);
+ public abstract void evaluationError (String message);
+
+ public Value getValue() {
+ return myValue;
+ }
+
+ public EvaluationContext getEvaluationContext() {
+ return myEvaluationContext;
+ }
+}
+
diff --git a/source/com/intellij/debugger/ui/tree/render/ToStringRenderer.java b/source/com/intellij/debugger/ui/tree/render/ToStringRenderer.java
new file mode 100644
index 000000000000..8a5274d6a044
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/ToStringRenderer.java
@@ -0,0 +1,108 @@
+package com.intellij.debugger.ui.tree.render;
+
+import com.intellij.debugger.DebuggerContext;
+import com.intellij.debugger.engine.StackFrameContext;
+import com.intellij.debugger.engine.DebugProcessImpl;
+import com.intellij.debugger.engine.evaluation.EvaluateException;
+import com.intellij.debugger.engine.evaluation.EvaluationContext;
+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.render.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.PsiExpression;
+import com.sun.jdi.*;
+
+import java.util.Iterator;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class ToStringRenderer extends NodeRendererImpl {
+ public static final String UNIQUE_ID = "ToStringRenderer";
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ToStringRenderer");
+
+ public ToStringRenderer() {
+ setEnabled(true);
+ }
+
+ public String getUniqueId() {
+ return UNIQUE_ID;
+ }
+
+ public String getName() {
+ return "toString";
+ }
+
+ public void setName(String name) {
+ // prohibit change
+ }
+
+ public ToStringRenderer clone() {
+ return (ToStringRenderer)super.clone();
+ }
+
+ public String calcLabel(final ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, final DescriptorLabelListener labelListener)
+ throws EvaluateException {
+ Value value = valueDescriptor.getValue();
+ BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) {
+ public void evaluationResult(String message) {
+ valueDescriptor.setValueLabel(message != null ? "\"" + message + "\"" : "");
+ labelListener.labelChanged();
+ }
+
+ public void evaluationError(String message) {
+ valueDescriptor.setValueLabelFailed(new EvaluateException(message + " Failed to evaluate toString() for this object", null));
+ labelListener.labelChanged();
+ }
+ });
+ return NodeDescriptor.EVALUATING_MESSAGE;
+ }
+
+ public boolean isApplicable(Type type) {
+ if(!(type instanceof ReferenceType)) {
+ return false;
+ }
+ if(type.name().equals("java.lang.String")) {
+ return false;
+ }
+ if(!overridesToString(type)) {
+ return false;
+ }
+ return true;
+ }
+
+ boolean overridesToString(Type type) {
+ if(type instanceof ClassType) {
+ ClassType classType = (ClassType)type;
+ java.util.List list = classType.methodsByName("toString", "()Ljava/lang/String;");
+ for (Iterator iterator = list.iterator(); iterator.hasNext();) {
+ Method method = (Method)iterator.next();
+ if(!(method.declaringType().name()).equals("java.lang.Object")){
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) {
+ getDefaultRenderer(value, evaluationContext).buildChildren(value, builder, evaluationContext);
+ }
+
+ private static NodeRenderer getDefaultRenderer(Value value, StackFrameContext context) {
+ Type type = value != null ? value.type() : null;
+ return ((DebugProcessImpl)context.getDebugProcess()).getDefaultRenderer(type);
+ }
+
+ public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException {
+ return getDefaultRenderer(((ValueDescriptor) node.getDescriptor()).getValue(), context).getChildValueExpression(node, context);
+ }
+
+ public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) {
+ return getDefaultRenderer(value, evaluationContext).isExpandable(value, evaluationContext, parentDescriptor);
+ }
+
+}
diff --git a/openapi/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java b/source/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java
similarity index 100%
rename from openapi/src/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java
rename to source/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java
diff --git a/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.form b/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.form
new file mode 100644
index 000000000000..b466f622a34c
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.form
@@ -0,0 +1,42 @@
+
+
diff --git a/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java b/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java
new file mode 100644
index 000000000000..5333c2a07909
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java
@@ -0,0 +1,67 @@
+package com.intellij.debugger.ui.tree.render.configurables;
+
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.ui.CompletitionEditor;
+import com.intellij.debugger.ui.tree.render.ExpressionChildrenRenderer;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.LabeledComponent;
+import com.intellij.psi.PsiClass;
+
+import javax.swing.*;
+import java.awt.*;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class ClassChildrenExpressionConfigurable implements UnnamedConfigurable{
+ private final Project myProject;
+ private final ExpressionChildrenRenderer myRenderer;
+
+ private JPanel myPanel;
+ private LabeledComponent myChildrenPanel;
+ private LabeledComponent myExpandablePanel;
+
+ private final CompletitionEditor myChildrenEditor;
+ private final CompletitionEditor myExpandableEditor;
+
+ public ClassChildrenExpressionConfigurable(Project project, ExpressionChildrenRenderer renderer) {
+ myProject = project;
+ myRenderer = renderer;
+
+ PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), myProject);
+ myChildrenEditor = DebuggerUtils.getInstance().createEditor(project, psiClass, "ClassChildrenExpression");
+ myExpandableEditor = DebuggerUtils.getInstance().createEditor(project, psiClass, "ClassChildrenExpression");
+
+ myChildrenPanel.getComponent().setLayout(new BorderLayout());
+ myChildrenPanel.getComponent().add(myChildrenEditor);
+
+ myExpandablePanel.getComponent().setLayout(new BorderLayout());
+ myExpandablePanel.getComponent().add(myExpandableEditor);
+ }
+
+ public JComponent createComponent() {
+ return myPanel;
+ }
+
+ public boolean isModified() {
+ return !myRenderer.getChildrenExpression().equals(myChildrenEditor.getText()) ||
+ !myRenderer.getChildrenExpandable().equals(myExpandableEditor.getText());
+ }
+
+ public void apply() throws ConfigurationException {
+ myRenderer.setChildrenExpression(myChildrenEditor.getText());
+ myRenderer.setChildrenExpandable(myExpandableEditor.getText());
+ }
+
+ public void reset() {
+ myChildrenEditor.setText(myRenderer.getChildrenExpression());
+ myExpandableEditor.setText(myRenderer.getChildrenExpandable());
+ }
+
+ public void disposeUIResources() {
+ }
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/configurables/ClassLabelExpressionConfigurable.java b/source/com/intellij/debugger/ui/tree/render/configurables/ClassLabelExpressionConfigurable.java
new file mode 100644
index 000000000000..d62efe3c0e67
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/configurables/ClassLabelExpressionConfigurable.java
@@ -0,0 +1,62 @@
+package com.intellij.debugger.ui.tree.render.configurables;
+
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.ui.CompletitionEditor;
+import com.intellij.debugger.ui.tree.render.LabelRenderer;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.LabeledComponent;
+import com.intellij.psi.PsiClass;
+
+import javax.swing.*;
+import java.awt.*;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class ClassLabelExpressionConfigurable implements UnnamedConfigurable{
+ private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.configurables.ClassLabelExpressionConfigurable");
+
+ private final Project myProject;
+ private final LabelRenderer myRenderer;
+ private LabeledComponent myCompletitionEditor;
+ private final JPanel myPanel;
+
+ public ClassLabelExpressionConfigurable(Project project, LabelRenderer renderer) {
+ LOG.assertTrue(project != null);
+ myProject = project;
+ myRenderer = renderer;
+
+ myCompletitionEditor = new LabeledComponent();
+ PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), myProject);
+ myCompletitionEditor.setComponent(DebuggerUtils.getInstance().createEditor(myProject, psiClass, "ClassLabelExpression"));
+ myCompletitionEditor.setText("Node label expression");
+
+ myPanel = new JPanel(new BorderLayout());
+ myPanel.add(myCompletitionEditor, BorderLayout.NORTH);
+ }
+
+ public JComponent createComponent() {
+ return myPanel;
+ }
+
+ public boolean isModified() {
+ return !myRenderer.getLabelExpression().equals(myCompletitionEditor.getComponent().getText());
+ }
+
+ public void apply() throws ConfigurationException {
+ myRenderer.setLabelExpression(myCompletitionEditor.getComponent().getText());
+ }
+
+ public void reset() {
+ myCompletitionEditor.getComponent().setText(myRenderer.getLabelExpression());
+ }
+
+ public void disposeUIResources() {
+ myCompletitionEditor = null;
+ }
+}
diff --git a/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.form b/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.form
new file mode 100644
index 000000000000..655e2b82931a
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.form
@@ -0,0 +1,103 @@
+
+
diff --git a/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java b/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java
new file mode 100644
index 000000000000..e4f67a51d6bd
--- /dev/null
+++ b/source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java
@@ -0,0 +1,172 @@
+package com.intellij.debugger.ui.tree.render.configurables;
+
+import com.intellij.debugger.engine.DebuggerUtils;
+import com.intellij.debugger.engine.evaluation.TextWithImports;
+import com.intellij.debugger.ui.CompletitionEditor;
+import com.intellij.debugger.ui.tree.render.EnumerationChildrenRenderer;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiClass;
+import com.intellij.ui.TableUtil;
+import com.intellij.util.ui.AbstractTableCellEditor;
+import com.intellij.util.ui.Table;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableModel;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/*
+ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved.
+ * Use is subject to license terms.
+ */
+
+public class NamedChildrenConfigurable implements UnnamedConfigurable{
+ private Table myTable;
+ private final Project myProject;
+ private final EnumerationChildrenRenderer myRenderer;
+ private JPanel myPanel;
+ private JLabel myTableLabel;
+ private JButton myButtonAdd;
+ private JButton myButtonRemove;
+ private JButton myButtonUp;
+ private JButton myButtonDown;
+
+ public NamedChildrenConfigurable(Project project, EnumerationChildrenRenderer renderer) {
+ myProject = project;
+ myRenderer = renderer;
+
+ myTableLabel.setLabelFor(myTable);
+
+ getModel().addColumn("Name", (Object[])null);
+ getModel().addColumn("Expression", (Object[])null);
+
+ PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), myProject);
+ final CompletitionEditor editor = DebuggerUtils.getInstance().createEditor(myProject, psiClass, "NamedChildrenConfigurable");
+
+ myTable.setDragEnabled(false);
+ myTable.setIntercellSpacing(new Dimension(0, 0));
+
+ myTable.getColumn("Expression").setCellEditor(new AbstractTableCellEditor() {
+ public Object getCellEditorValue() {
+ return editor.getText();
+ }
+
+ public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+ editor.setText((TextWithImports)value);
+ return editor;
+ }
+ });
+
+ myButtonAdd.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ getModel().addRow(new Object[] {"", DebuggerUtils.getInstance().createExpressionWithImports("") });
+ }
+ });
+
+ myButtonRemove.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ int selectedRow = myTable.getSelectedRow();
+ if(selectedRow >= 0 && selectedRow < myTable.getRowCount()) {
+ getModel().removeRow(selectedRow);
+ }
+ }
+ });
+
+ myButtonDown.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ TableUtil.moveSelectedItemsDown(myTable);
+ }
+ });
+
+ myButtonUp.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ TableUtil.moveSelectedItemsUp(myTable);
+ }
+ });
+
+ myTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ updateButtons();
+ }
+ });
+ updateButtons();
+ }
+
+ private void updateButtons() {
+ int selectedRow = myTable.getSelectedRow();
+ myButtonRemove.setEnabled(selectedRow != -1);
+ myButtonUp.setEnabled(selectedRow > 0);
+ myButtonDown.setEnabled(selectedRow < myTable.getRowCount() - 1);
+ }
+
+ private DefaultTableModel getModel() {
+ return ((DefaultTableModel)myTable.getModel());
+ }
+
+ public JComponent createComponent() {
+ return myPanel;
+ }
+
+ public boolean isModified() {
+ return false;
+ }
+
+ public void apply() throws ConfigurationException {
+ DefaultTableModel model = getModel();
+
+ final int size = model.getRowCount();
+ java.util.List> result = new ArrayList>();
+
+ for (int idx = 0; idx < size; idx++) {
+ result.add(new Pair((String)model.getValueAt(idx, 0), (TextWithImports)model.getValueAt(idx, 1)));
+ }
+ myRenderer.setChildren(result);
+ }
+
+ public void reset() {
+ while(myTable.getModel().getRowCount() > 0) {
+ getModel().removeRow(0);
+ }
+
+ for (Iterator> iterator = myRenderer.getChildren().iterator(); iterator.hasNext();) {
+ Pair pair = iterator.next();
+ getModel().addRow(new Object[] { pair.getFirst(), pair.getSecond()});
+ }
+ }
+
+ public void disposeUIResources() {
+ }
+
+
+ /*
+ private class TextWithImportsTableRenderer implements TableCellRenderer{
+ private final CompletitionEditor myEditor;
+
+ private TextWithImportsTableRenderer () {
+ PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), myProject);
+ myEditor = DebuggerUtils.getInstance().createEditor(myProject, psiClass, "NamedChildrenConfigurable");
+ }
+
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ if(hasFocus) {
+ myEditor.setText((TextWithImports)value);
+ return myEditor;
+ }
+ else {
+ TableCellRenderer defaultRenderer = myTable.getDefaultRenderer(String.class);
+ return defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+ }
+ }
+ }
+ */
+
+}