From bfe82dc83a75d544fa3ff4054e33414a2a195961 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Wed, 16 Feb 2005 17:14:18 +0300 Subject: [PATCH] removed DebuggerCommonViews plugin and moved its functionality to IDEA --- .../debugger/engine/DebugProcess.java | 10 +- .../debugger/engine/DebuggerUtils.java | 8 +- .../ui/tree/render/NodeRendererImpl.java | 40 ---- .../ui/tree/render/ReferenceRenderer.java | 54 ----- .../src/actions/ShowAllAsHex.java | 16 -- resources/src/componentSets/Debugger.xml | 18 +- .../actions/AdjustArrayRangeAction.java | 3 +- .../debugger/actions/ViewAsGroup.java | 2 +- .../debugger/engine/DebugProcessImpl.java | 103 +++++++-- .../settings/ArrayRendererConfigurable.java | 45 ++-- .../settings/NodeRendererSettings.java | 198 +++++++++++++++++ ...gsImpl.java => RendererConfiguration.java} | 101 ++------- .../settings/ViewsGeneralConfigurable.java | 65 +++--- .../settings/ViewsGeneralSettings.java | 23 +- .../ui/impl/nodes/ArrayIndexHelper.java | 3 +- .../debugger/ui/impl/watch/DebuggerTree.java | 2 +- .../ui/impl/watch/ValueDescriptorImpl.java | 2 +- .../debugger/ui/tree}/actions/ShowAllAs.java | 2 +- .../ui/tree}/actions/ShowAllAsDecimal.java | 2 +- .../ui/tree/actions/ShowAllAsHex.java | 20 ++ .../watch => tree}/render/ArrayRenderer.java | 35 +-- .../tree/render/BasicRendererProperties.java | 106 ++++++++++ .../ui/tree/render/BatchEvaluator.java | 199 ++++++++++++++++++ .../ui/tree/render/CachedEvaluator.java | 89 ++++++++ .../ui/tree/render/ChildrenBuilder.java | 0 .../ui/tree/render/ChildrenRenderer.java | 0 .../watch => tree}/render/ClassRenderer.java | 33 +-- .../tree/render/CompoundNodeConfigurable.java | 0 .../ui/tree/render/CompoundNodeRenderer.java | 29 +-- .../render/CompoundReferenceRenderer.java | 67 ++++++ .../tree/render/DescriptorLabelListener.java | 0 .../render/EnumerationChildrenRenderer.java | 105 +++++++++ .../render/ExpressionChildrenRenderer.java | 171 +++++++++++++++ .../debugger/ui/tree/render/HexRenderer.java | 113 ++++++++++ .../ui/tree/render/LabelRenderer.java | 97 +++++++++ .../debugger/ui/tree/render/NodeRenderer.java | 4 + .../ui/tree/render/NodeRendererImpl.java | 59 ++++++ .../render/NodeRendererSettingsListener.java | 0 .../render/PrimitiveRenderer.java | 42 ++-- .../ui/tree/render/ReferenceRenderer.java | 59 ++++++ .../debugger/ui/tree/render/Renderer.java | 5 - .../ui/tree/render/RendererProvider.java | 0 .../ui/tree/render/ToStringCommand.java | 58 +++++ .../ui/tree/render/ToStringRenderer.java | 108 ++++++++++ .../ui/tree/render/ValueLabelRenderer.java | 0 .../ClassChildrenExpressionConfigurable.form | 42 ++++ .../ClassChildrenExpressionConfigurable.java | 67 ++++++ .../ClassLabelExpressionConfigurable.java | 62 ++++++ .../NamedChildrenConfigurable.form | 103 +++++++++ .../NamedChildrenConfigurable.java | 172 +++++++++++++++ 50 files changed, 2171 insertions(+), 371 deletions(-) delete mode 100644 openapi/src/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java delete mode 100644 openapi/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java delete mode 100644 plugins/debuggerCommonViews/src/actions/ShowAllAsHex.java create mode 100644 source/com/intellij/debugger/settings/NodeRendererSettings.java rename source/com/intellij/debugger/settings/{NodeRendererSettingsImpl.java => RendererConfiguration.java} (51%) rename {plugins/debuggerCommonViews/src => source/com/intellij/debugger/ui/tree}/actions/ShowAllAs.java (98%) rename {plugins/debuggerCommonViews/src => source/com/intellij/debugger/ui/tree}/actions/ShowAllAsDecimal.java (87%) create mode 100644 source/com/intellij/debugger/ui/tree/actions/ShowAllAsHex.java rename source/com/intellij/debugger/ui/{impl/watch => tree}/render/ArrayRenderer.java (92%) create mode 100644 source/com/intellij/debugger/ui/tree/render/BasicRendererProperties.java create mode 100644 source/com/intellij/debugger/ui/tree/render/BatchEvaluator.java create mode 100644 source/com/intellij/debugger/ui/tree/render/CachedEvaluator.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java (100%) rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/ChildrenRenderer.java (100%) rename source/com/intellij/debugger/ui/{impl/watch => tree}/render/ClassRenderer.java (92%) rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/CompoundNodeConfigurable.java (100%) rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/CompoundNodeRenderer.java (72%) create mode 100644 source/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/DescriptorLabelListener.java (100%) create mode 100644 source/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java create mode 100644 source/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java create mode 100644 source/com/intellij/debugger/ui/tree/render/HexRenderer.java create mode 100644 source/com/intellij/debugger/ui/tree/render/LabelRenderer.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/NodeRenderer.java (82%) create mode 100644 source/com/intellij/debugger/ui/tree/render/NodeRendererImpl.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/NodeRendererSettingsListener.java (100%) rename source/com/intellij/debugger/ui/{impl/watch => tree}/render/PrimitiveRenderer.java (75%) create mode 100644 source/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/Renderer.java (80%) rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/RendererProvider.java (100%) create mode 100644 source/com/intellij/debugger/ui/tree/render/ToStringCommand.java create mode 100644 source/com/intellij/debugger/ui/tree/render/ToStringRenderer.java rename {openapi/src => source}/com/intellij/debugger/ui/tree/render/ValueLabelRenderer.java (100%) create mode 100644 source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.form create mode 100644 source/com/intellij/debugger/ui/tree/render/configurables/ClassChildrenExpressionConfigurable.java create mode 100644 source/com/intellij/debugger/ui/tree/render/configurables/ClassLabelExpressionConfigurable.java create mode 100644 source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.form create mode 100644 source/com/intellij/debugger/ui/tree/render/configurables/NamedChildrenConfigurable.java 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); + } + } + } + */ + +}