a34e8a1934d0f66ed0bbbcdf432da84a767ebed0
[idea/community.git] / java / debugger / impl / src / com / intellij / debugger / actions / ViewAsGroup.java
1 /*
2  * Copyright 2000-2014 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.debugger.actions;
17
18 import com.intellij.debugger.engine.DebugProcessImpl;
19 import com.intellij.debugger.engine.JavaValue;
20 import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
21 import com.intellij.debugger.impl.DebuggerContextImpl;
22 import com.intellij.debugger.settings.NodeRendererSettings;
23 import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
24 import com.intellij.debugger.ui.tree.render.NodeRenderer;
25 import com.intellij.openapi.actionSystem.*;
26 import com.intellij.openapi.diagnostic.Logger;
27 import com.intellij.openapi.project.DumbAware;
28 import com.intellij.xdebugger.frame.XValue;
29 import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
30 import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
31 import org.jetbrains.annotations.NotNull;
32 import org.jetbrains.annotations.Nullable;
33
34 import java.util.ArrayList;
35 import java.util.Collections;
36 import java.util.List;
37
38 /**
39  * User: lex
40  * Date: Sep 26, 2003
41  * Time: 11:05:57 PM
42  */
43 public class ViewAsGroup extends ActionGroup implements DumbAware {
44   private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.ViewAsGroup");
45
46   private AnAction[] myChildren = AnAction.EMPTY_ARRAY;
47
48   public ViewAsGroup() {
49     super(null, true);
50   }
51
52   private static class RendererAction extends ToggleAction {
53     private final NodeRenderer myNodeRenderer;
54
55     public RendererAction(NodeRenderer nodeRenderer) {
56       super(nodeRenderer.getName());
57       myNodeRenderer = nodeRenderer;
58     }
59
60     public boolean isSelected(AnActionEvent e) {
61       List<JavaValue> values = getSelectedValues(e);
62       if (values.isEmpty()) {
63         return false;
64       }
65       for (JavaValue value : values) {
66         if (value.getDescriptor().getLastRenderer() != myNodeRenderer) {
67           return false;
68         }
69       }
70       return true;
71     }
72
73     public void setSelected(final AnActionEvent e, final boolean state) {
74       if (!state) return;
75
76       final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext());
77       final List<JavaValue> values = getSelectedValues(e);
78       final List<XValueNodeImpl> selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(e.getDataContext());
79
80       LOG.assertTrue(debuggerContext != null && !values.isEmpty());
81
82       DebugProcessImpl process = debuggerContext.getDebugProcess();
83       if (process == null) {
84         return;
85       }
86
87       process.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
88           public void threadAction() {
89             for (final XValueNodeImpl node : selectedNodes) {
90               final XValue container = node.getValueContainer();
91               if (container instanceof JavaValue) {
92                 ((JavaValue)container).setRenderer(myNodeRenderer, node);
93               }
94             }
95           }
96         }
97       );
98     }
99   }
100
101   @NotNull
102   public AnAction[] getChildren(@Nullable final AnActionEvent e) {
103     return myChildren;
104   }
105
106   private static AnAction [] calcChildren(List<JavaValue> values) {
107     List<AnAction> renderers = new ArrayList<AnAction>();
108
109     List<NodeRenderer> allRenderers = NodeRendererSettings.getInstance().getAllRenderers();
110
111     boolean anyValueDescriptor = false;
112
113     for (NodeRenderer nodeRenderer : allRenderers) {
114       boolean allApp = true;
115
116       for (JavaValue value : values) {
117         ValueDescriptorImpl valueDescriptor = value.getDescriptor();
118         anyValueDescriptor = true;
119         if (!valueDescriptor.isValueValid() || !nodeRenderer.isApplicable(valueDescriptor.getType())) {
120           allApp = false;
121           break;
122         }
123       }
124
125       if (!anyValueDescriptor) {
126         return AnAction.EMPTY_ARRAY;
127       }
128
129       if (allApp) {
130         renderers.add(new RendererAction(nodeRenderer));
131       }
132     }
133
134     List<AnAction> children = new ArrayList<AnAction>();
135     AnAction[] viewAsActions = ((DefaultActionGroup) ActionManager.getInstance().getAction(DebuggerActions.REPRESENTATION_LIST)).getChildren(null);
136     for (AnAction viewAsAction : viewAsActions) {
137       if (viewAsAction instanceof AutoRendererAction) {
138         if (renderers.size() > 1) {
139           viewAsAction.getTemplatePresentation().setVisible(true);
140           children.add(viewAsAction);
141         }
142       }
143       else {
144         children.add(viewAsAction);
145       }
146     }
147
148     if (!children.isEmpty()) {
149       children.add(Separator.getInstance());
150     }
151     children.addAll(renderers);
152
153     return children.toArray(new AnAction[children.size()]);
154   }
155
156   public void update(final AnActionEvent event) {
157     if(!DebuggerAction.isFirstStart(event)) {
158       return;
159     }
160
161     final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(event.getDataContext());
162     final List<JavaValue> values = getSelectedValues(event);
163     if (values.isEmpty()) {
164       return;
165     }
166
167     final DebugProcessImpl process = debuggerContext.getDebugProcess();
168     if (process == null) {
169       event.getPresentation().setEnabled(false);
170       return;
171     }
172     
173     process.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) {
174       public void threadAction() {
175         myChildren = calcChildren(values);
176         DebuggerAction.enableAction(event, myChildren.length > 0);
177       }
178     });
179   }
180
181   public static List<JavaValue> getSelectedValues(AnActionEvent event) {
182     List<XValueNodeImpl> selectedNodes = XDebuggerTreeActionBase.getSelectedNodes(event.getDataContext());
183     if (selectedNodes.isEmpty()) return Collections.emptyList();
184
185     List<JavaValue> res = new ArrayList<JavaValue>(selectedNodes.size());
186     for (XValueNodeImpl node : selectedNodes) {
187       XValue container = node.getValueContainer();
188       if (container instanceof JavaValue) {
189         res.add((JavaValue)container);
190       }
191     }
192     return res;
193   }
194 }