mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
removed now unused classes from java debugger - pt.2
This commit is contained in:
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
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.ValueDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.progress.util.ProgressWindowWithNotification;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* @author Jeka
|
||||
*/
|
||||
public abstract class BaseValueAction extends DebuggerAction {
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final DataContext actionContext = e.getDataContext();
|
||||
final Project project = CommonDataKeys.PROJECT.getData(actionContext);
|
||||
final DebuggerTreeNodeImpl node = getSelectedNode(actionContext);
|
||||
final String text = getValueText(node);
|
||||
if (text != null) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
public void run() {
|
||||
processText(project, DebuggerUtilsEx.prepareValueText(text, project), node, null);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Value value = getValue(node);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
final DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project);
|
||||
if(debuggerManager == null) {
|
||||
return;
|
||||
}
|
||||
final DebuggerContextImpl debuggerContext = debuggerManager.getContext();
|
||||
if (debuggerContext == null || debuggerContext.getDebuggerSession() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, project);
|
||||
SuspendContextCommandImpl getTextCommand = new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) {
|
||||
public Priority getPriority() {
|
||||
return Priority.HIGH;
|
||||
}
|
||||
|
||||
public void contextAction() throws Exception {
|
||||
//noinspection HardCodedStringLiteral
|
||||
progressWindow.setText(DebuggerBundle.message("progress.evaluating", "toString()"));
|
||||
|
||||
final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(debuggerContext.createEvaluationContext(), value);
|
||||
|
||||
if (progressWindow.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
public void run() {
|
||||
String text = valueAsString;
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
processText(project, text, node, debuggerContext);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
progressWindow.setTitle(DebuggerBundle.message("title.evaluating"));
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(getTextCommand, progressWindow);
|
||||
}
|
||||
|
||||
protected abstract void processText(final Project project, String text, DebuggerTreeNodeImpl node, DebuggerContextImpl debuggerContext);
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
Presentation presentation = e.getPresentation();
|
||||
Value value = getValue(getSelectedNode(e.getDataContext()));
|
||||
presentation.setEnabled(value != null);
|
||||
presentation.setVisible(value != null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getValueText(final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (descriptor instanceof ValueDescriptorImpl) {
|
||||
return ((ValueDescriptorImpl)descriptor).getValueText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Value getValue(final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (!(descriptor instanceof ValueDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
return ((ValueDescriptor)descriptor).getValue();
|
||||
}
|
||||
}
|
||||
@@ -415,166 +415,166 @@ public class JavaValueModifier extends XValueModifier {
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(askSetAction, progressWindow);
|
||||
}
|
||||
|
||||
private void showEditor(final TextWithImports initialString,
|
||||
final DebuggerTreeNodeImpl node,
|
||||
final DebuggerContextImpl debuggerContext,
|
||||
final SetValueRunnable setValueRunnable) {
|
||||
final JPanel editorPanel = new JPanel();
|
||||
editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.X_AXIS));
|
||||
SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
label.setIcon(node.getIcon());
|
||||
DebuggerTreeRenderer.getDescriptorTitle(debuggerContext, node.getDescriptor()).appendToComponent(label);
|
||||
editorPanel.add(label);
|
||||
|
||||
final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(
|
||||
debuggerContext.getProject(),
|
||||
PositionUtil.getContextElement(debuggerContext),
|
||||
"setValue", DefaultCodeFragmentFactory.getInstance());
|
||||
comboBox.setText(initialString);
|
||||
comboBox.selectAll();
|
||||
editorPanel.add(comboBox);
|
||||
|
||||
final DebuggerTreeInplaceEditor editor = new DebuggerTreeInplaceEditor(node) {
|
||||
public JComponent createInplaceEditorComponent() {
|
||||
return editorPanel;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
public Editor getEditor() {
|
||||
return comboBox.getEditor();
|
||||
}
|
||||
|
||||
public JComponent getEditorComponent() {
|
||||
return comboBox.getEditorComponent();
|
||||
}
|
||||
|
||||
private void flushValue() {
|
||||
if (comboBox.isPopupVisible()) {
|
||||
comboBox.selectPopupValue();
|
||||
}
|
||||
|
||||
Editor editor = getEditor();
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TextWithImports text = comboBox.getText();
|
||||
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(debuggerContext.getProject()).getPsiFile(editor.getDocument());
|
||||
|
||||
final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, getProject());
|
||||
EditorEvaluationCommand evaluationCommand = new EditorEvaluationCommand(getEditor(), psiFile, debuggerContext, progressWindow) {
|
||||
public void threadAction() {
|
||||
try {
|
||||
evaluate();
|
||||
}
|
||||
catch(EvaluateException e) {
|
||||
progressWindow.cancel();
|
||||
}
|
||||
catch(ProcessCanceledException e) {
|
||||
progressWindow.cancel();
|
||||
}
|
||||
finally{
|
||||
if (!progressWindow.isCanceled()) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(debuggerContext.getProject(), new Runnable() {
|
||||
public void run() {
|
||||
comboBox.addRecent(text);
|
||||
cancelEditing();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable<ExpressionEvaluator>() {
|
||||
public ExpressionEvaluator compute() throws EvaluateException {
|
||||
return EvaluatorBuilderImpl.build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
|
||||
}
|
||||
});
|
||||
|
||||
setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() {
|
||||
public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException,
|
||||
InvalidTypeException,
|
||||
EvaluateException,
|
||||
IncompatibleThreadStateException {
|
||||
if (!progressWindow.isCanceled()) {
|
||||
setValueRunnable.setValue(evaluationContext, newValue);
|
||||
node.calcValue();
|
||||
}
|
||||
}
|
||||
|
||||
public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws
|
||||
InvocationException,
|
||||
ClassNotLoadedException,
|
||||
EvaluateException,
|
||||
IncompatibleThreadStateException,
|
||||
InvalidTypeException {
|
||||
return setValueRunnable.loadClass(evaluationContext, className);
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
progressWindow.addListener(new ProgressIndicatorListenerAdapter() {
|
||||
//should return whether to stop processing
|
||||
public void stopped() {
|
||||
if(!progressWindow.isCanceled()) {
|
||||
IJSwingUtilities.invoke(new Runnable() {
|
||||
public void run() {
|
||||
cancelEditing();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
progressWindow.setTitle(DebuggerBundle.message("progress.set.value"));
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(evaluationCommand, progressWindow);
|
||||
}
|
||||
|
||||
public void cancelEditing() {
|
||||
try {
|
||||
super.cancelEditing();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void doOKAction() {
|
||||
try {
|
||||
flushValue();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final DebuggerStateManager stateManager = DebuggerManagerEx.getInstanceEx(debuggerContext.getProject()).getContextManager();
|
||||
|
||||
stateManager.addListener(new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
stateManager.removeListener(this);
|
||||
editor.cancelEditing();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
node.getTree().hideTooltip();
|
||||
|
||||
editor.show();
|
||||
}
|
||||
//private void showEditor(final TextWithImports initialString,
|
||||
// final DebuggerTreeNodeImpl node,
|
||||
// final DebuggerContextImpl debuggerContext,
|
||||
// final SetValueRunnable setValueRunnable) {
|
||||
// final JPanel editorPanel = new JPanel();
|
||||
// editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.X_AXIS));
|
||||
// SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
// label.setIcon(node.getIcon());
|
||||
// DebuggerTreeRenderer.getDescriptorTitle(debuggerContext, node.getDescriptor()).appendToComponent(label);
|
||||
// editorPanel.add(label);
|
||||
//
|
||||
// final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(
|
||||
// debuggerContext.getProject(),
|
||||
// PositionUtil.getContextElement(debuggerContext),
|
||||
// "setValue", DefaultCodeFragmentFactory.getInstance());
|
||||
// comboBox.setText(initialString);
|
||||
// comboBox.selectAll();
|
||||
// editorPanel.add(comboBox);
|
||||
//
|
||||
// final DebuggerTreeInplaceEditor editor = new DebuggerTreeInplaceEditor(node) {
|
||||
// public JComponent createInplaceEditorComponent() {
|
||||
// return editorPanel;
|
||||
// }
|
||||
//
|
||||
// public JComponent getPreferredFocusedComponent() {
|
||||
// return comboBox;
|
||||
// }
|
||||
//
|
||||
// public Editor getEditor() {
|
||||
// return comboBox.getEditor();
|
||||
// }
|
||||
//
|
||||
// public JComponent getEditorComponent() {
|
||||
// return comboBox.getEditorComponent();
|
||||
// }
|
||||
//
|
||||
// private void flushValue() {
|
||||
// if (comboBox.isPopupVisible()) {
|
||||
// comboBox.selectPopupValue();
|
||||
// }
|
||||
//
|
||||
// Editor editor = getEditor();
|
||||
// if(editor == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// final TextWithImports text = comboBox.getText();
|
||||
//
|
||||
// PsiFile psiFile = PsiDocumentManager.getInstance(debuggerContext.getProject()).getPsiFile(editor.getDocument());
|
||||
//
|
||||
// final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, getProject());
|
||||
// EditorEvaluationCommand evaluationCommand = new EditorEvaluationCommand(getEditor(), psiFile, debuggerContext, progressWindow) {
|
||||
// public void threadAction() {
|
||||
// try {
|
||||
// evaluate();
|
||||
// }
|
||||
// catch(EvaluateException e) {
|
||||
// progressWindow.cancel();
|
||||
// }
|
||||
// catch(ProcessCanceledException e) {
|
||||
// progressWindow.cancel();
|
||||
// }
|
||||
// finally{
|
||||
// if (!progressWindow.isCanceled()) {
|
||||
// DebuggerInvocationUtil.swingInvokeLater(debuggerContext.getProject(), new Runnable() {
|
||||
// public void run() {
|
||||
// comboBox.addRecent(text);
|
||||
// cancelEditing();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
// ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable<ExpressionEvaluator>() {
|
||||
// public ExpressionEvaluator compute() throws EvaluateException {
|
||||
// return EvaluatorBuilderImpl.build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() {
|
||||
// public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException,
|
||||
// InvalidTypeException,
|
||||
// EvaluateException,
|
||||
// IncompatibleThreadStateException {
|
||||
// if (!progressWindow.isCanceled()) {
|
||||
// setValueRunnable.setValue(evaluationContext, newValue);
|
||||
// node.calcValue();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws
|
||||
// InvocationException,
|
||||
// ClassNotLoadedException,
|
||||
// EvaluateException,
|
||||
// IncompatibleThreadStateException,
|
||||
// InvalidTypeException {
|
||||
// return setValueRunnable.loadClass(evaluationContext, className);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// progressWindow.addListener(new ProgressIndicatorListenerAdapter() {
|
||||
// //should return whether to stop processing
|
||||
// public void stopped() {
|
||||
// if(!progressWindow.isCanceled()) {
|
||||
// IJSwingUtilities.invoke(new Runnable() {
|
||||
// public void run() {
|
||||
// cancelEditing();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// });
|
||||
//
|
||||
// progressWindow.setTitle(DebuggerBundle.message("progress.set.value"));
|
||||
// debuggerContext.getDebugProcess().getManagerThread().startProgress(evaluationCommand, progressWindow);
|
||||
// }
|
||||
//
|
||||
// public void cancelEditing() {
|
||||
// try {
|
||||
// super.cancelEditing();
|
||||
// }
|
||||
// finally {
|
||||
// comboBox.dispose();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void doOKAction() {
|
||||
// try {
|
||||
// flushValue();
|
||||
// }
|
||||
// finally {
|
||||
// comboBox.dispose();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// };
|
||||
//
|
||||
// final DebuggerStateManager stateManager = DebuggerManagerEx.getInstanceEx(debuggerContext.getProject()).getContextManager();
|
||||
//
|
||||
// stateManager.addListener(new DebuggerContextListener() {
|
||||
// public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
// if (event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
// stateManager.removeListener(this);
|
||||
// editor.cancelEditing();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// node.getTree().hideTooltip();
|
||||
//
|
||||
// editor.show();
|
||||
//}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static String getDisplayableString(PrimitiveValue value, boolean showAsHex) {
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: Jul 15, 2003
|
||||
* Time: 6:38:23 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public interface VMEventListener {
|
||||
//aware! called in DebuggerEventThread
|
||||
void vmEvent(com.sun.jdi.event.Event event);
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.sun.jdi.Field;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Oct 15, 2003
|
||||
* Time: 11:38:25 PM
|
||||
*/
|
||||
public interface InspectField extends InspectEntity{
|
||||
ObjectReference getObject();
|
||||
Field getField ();
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.sun.jdi.LocalVariable;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Oct 15, 2003
|
||||
* Time: 11:39:04 PM
|
||||
*
|
||||
* todo [lex] does this interface really required?
|
||||
*/
|
||||
public interface InspectLocal extends InspectEntity{
|
||||
StackFrameProxyImpl getStackFrame();
|
||||
LocalVariable getLocal ();
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Sep 16, 2003
|
||||
* Time: 6:43:46 PM
|
||||
*/
|
||||
public class CompletedInputDialog extends DialogWrapper {
|
||||
JPanel myPanel;
|
||||
DebuggerExpressionComboBox myCombo;
|
||||
PsiElement myContext;
|
||||
Project myProject;
|
||||
private JLabel myLabel;
|
||||
|
||||
public CompletedInputDialog(String title, String okText, Project project) {
|
||||
super(project, false);
|
||||
setTitle(title);
|
||||
setOKButtonText(okText);
|
||||
myProject = project;
|
||||
setModal(false);
|
||||
DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext();
|
||||
myContext = PositionUtil.getContextElement(debuggerContext);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myCombo.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
myPanel = new JPanel(new GridBagLayout());
|
||||
myLabel = new JLabel(DebuggerBundle.message("label.complete.input.dialog.expression"));
|
||||
myPanel.add(myLabel, new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
|
||||
new Insets(0, 1, 0, 1), 0, 0));
|
||||
|
||||
myCombo = new DebuggerExpressionComboBox(myProject, myContext, "evaluation", DefaultCodeFragmentFactory.getInstance());
|
||||
myCombo.selectAll();
|
||||
|
||||
myPanel.add(myCombo, new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(0, 1, 0, 1), 0, 0));
|
||||
myPanel.setPreferredSize(JBUI.size(200, 50));
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public TextWithImports getExpressionText() {
|
||||
return myCombo.getText();
|
||||
}
|
||||
|
||||
public DebuggerExpressionComboBox getCombo() {
|
||||
return myCombo;
|
||||
}
|
||||
|
||||
public void setExpressionLabel(String text) {
|
||||
myLabel.setText(text);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
myCombo.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Lex
|
||||
*/
|
||||
public class DebuggerRecents {
|
||||
private final Map<Object, LinkedList<TextWithImports>> myRecentExpressions = new HashMap<Object, LinkedList<TextWithImports>>();
|
||||
|
||||
public static DebuggerRecents getInstance(Project project) {
|
||||
return ServiceManager.getService(project, DebuggerRecents.class);
|
||||
}
|
||||
|
||||
public LinkedList<TextWithImports> getRecents(Object id) {
|
||||
LinkedList<TextWithImports> result = myRecentExpressions.get(id);
|
||||
if(result == null){
|
||||
result = new LinkedList<TextWithImports>();
|
||||
myRecentExpressions.put(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addRecent(Object id, TextWithImports recent) {
|
||||
LinkedList<TextWithImports> recents = getRecents(id);
|
||||
if(recents.size() >= DebuggerExpressionComboBox.MAX_ROWS) {
|
||||
recents.removeLast();
|
||||
}
|
||||
recents.remove(recent);
|
||||
recents.addFirst(recent);
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* @author lex
|
||||
*/
|
||||
public class DebuggerStatementEditor extends DebuggerEditorImpl {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerStatementEditor");
|
||||
|
||||
private final EditorTextField myEditor;
|
||||
|
||||
private int myRecentIdx;
|
||||
|
||||
public DebuggerStatementEditor(Project project, PsiElement context, @NonNls String recentsId, final CodeFragmentFactory factory) {
|
||||
super(project, context, recentsId, factory);
|
||||
myRecentIdx = getRecentItemsCount();
|
||||
final Document document = EditorFactory.getInstance().createDocument("");
|
||||
myEditor = new EditorTextField(document, project, factory.getFileType(), false, false) {
|
||||
protected EditorEx createEditor() {
|
||||
EditorEx editor = super.createEditor();
|
||||
editor.setVerticalScrollbarVisible(true);
|
||||
editor.setHorizontalScrollbarVisible(true);
|
||||
return editor;
|
||||
}
|
||||
};
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(addChooseFactoryLabel(myEditor, true));
|
||||
|
||||
DefaultActionGroup actionGroup = new DefaultActionGroup(null, false);
|
||||
actionGroup.add(new ItemAction(IdeActions.ACTION_PREVIOUS_OCCURENCE, this){
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
LOG.assertTrue(myRecentIdx >= 0);
|
||||
// since recents are stored in a stack, previous item is at currentIndex + 1
|
||||
myRecentIdx += 1;
|
||||
updateTextFromRecents();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myRecentIdx < getRecentItemsCount());
|
||||
}
|
||||
});
|
||||
actionGroup.add(new ItemAction(IdeActions.ACTION_NEXT_OCCURENCE, this){
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.assertTrue(myRecentIdx < getRecentItemsCount());
|
||||
}
|
||||
// since recents are stored in a stack, next item is at currentIndex - 1
|
||||
myRecentIdx -= 1;
|
||||
updateTextFromRecents();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myRecentIdx > 0);
|
||||
}
|
||||
});
|
||||
|
||||
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.COMBO_PAGER, actionGroup, false).getComponent(),
|
||||
BorderLayout.EAST);
|
||||
|
||||
setText(new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, ""));
|
||||
}
|
||||
|
||||
private void updateTextFromRecents() {
|
||||
List<TextWithImports> recents = getRecents();
|
||||
LOG.assertTrue(myRecentIdx <= recents.size());
|
||||
setText(myRecentIdx < recents.size() ? recents.get(myRecentIdx) : new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""));
|
||||
}
|
||||
|
||||
private List<TextWithImports> getRecents() {
|
||||
final LinkedList<TextWithImports> recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId());
|
||||
final ArrayList<TextWithImports> reversed = new ArrayList<TextWithImports>(recents.size());
|
||||
for (final ListIterator<TextWithImports> it = recents.listIterator(recents.size()); it.hasPrevious();) {
|
||||
reversed.add(it.previous());
|
||||
}
|
||||
return reversed;
|
||||
}
|
||||
|
||||
private int getRecentItemsCount() {
|
||||
return DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()).size();
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
final Editor editor = myEditor.getEditor();
|
||||
return editor != null? editor.getContentComponent() : myEditor;
|
||||
}
|
||||
|
||||
public TextWithImports getText() {
|
||||
return createItem(myEditor.getDocument(), getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doSetText(TextWithImports text) {
|
||||
restoreFactory(text);
|
||||
myEditor.setNewDocumentAndFileType(getCurrentFactory().getFileType(), createDocument(text));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateEditorUi() {
|
||||
final Editor editor = myEditor.getEditor();
|
||||
if (editor != null) {
|
||||
DaemonCodeAnalyzer.getInstance(getProject()).updateVisibleHighlighters(editor);
|
||||
}
|
||||
}
|
||||
|
||||
public TextWithImports createText(String text, String importsString) {
|
||||
return new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, text, importsString, getCurrentFactory().getFileType());
|
||||
}
|
||||
|
||||
private static abstract class ItemAction extends AnAction {
|
||||
public ItemAction(String sourceActionName, JComponent component) {
|
||||
copyFrom(ActionManager.getInstance().getAction(sourceActionName));
|
||||
registerCustomShortcutSet(getShortcutSet(), component);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextListener;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.debugger.ui.impl.ValueNodeDnD;
|
||||
import com.intellij.debugger.ui.impl.WatchDebuggerTree;
|
||||
import com.intellij.debugger.ui.impl.WatchPanel;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.xdebugger.XDebuggerBundle;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class EvaluationDialog extends DialogWrapper {
|
||||
private final MyEvaluationPanel myEvaluationPanel;
|
||||
private final Project myProject;
|
||||
private final DebuggerContextListener myContextListener;
|
||||
private final DebuggerEditorImpl myEditor;
|
||||
private final List<Runnable> myDisposeRunnables = new ArrayList<Runnable>();
|
||||
|
||||
public EvaluationDialog(Project project, TextWithImports text) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
setModal(false);
|
||||
setCancelButtonText(CommonBundle.message("button.close"));
|
||||
setOKButtonText(DebuggerBundle.message("button.evaluate"));
|
||||
|
||||
myEvaluationPanel = new MyEvaluationPanel(myProject);
|
||||
|
||||
myEditor = createEditor(DefaultCodeFragmentFactory.getInstance());
|
||||
|
||||
setDebuggerContext(getDebuggerContext());
|
||||
initDialogData(text);
|
||||
|
||||
myContextListener = new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
boolean close = true;
|
||||
for (DebuggerSession session : DebuggerManagerEx.getInstanceEx(myProject).getSessions()) {
|
||||
if (!session.isStopped()) {
|
||||
close = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(close) {
|
||||
close(CANCEL_EXIT_CODE);
|
||||
}
|
||||
else {
|
||||
setDebuggerContext(newContext);
|
||||
}
|
||||
}
|
||||
};
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getContextManager().addListener(myContextListener);
|
||||
|
||||
setHorizontalStretch(1f);
|
||||
setVerticalStretch(1f);
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
if (isOKActionEnabled()) {
|
||||
doEvaluate();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doEvaluate() {
|
||||
if (myEditor == null || myEvaluationPanel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myEvaluationPanel.clear();
|
||||
TextWithImports codeToEvaluate = getCodeToEvaluate();
|
||||
if (codeToEvaluate == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setOKActionEnabled(false);
|
||||
NodeDescriptorImpl descriptor = myEvaluationPanel.getWatchTree().addWatch(codeToEvaluate, "result").getDescriptor();
|
||||
//if (descriptor instanceof EvaluationDescriptor) {
|
||||
// final EvaluationDescriptor evalDescriptor = (EvaluationDescriptor)descriptor;
|
||||
// evalDescriptor.setCodeFragmentFactory(myEditor.getCurrentFactory());
|
||||
//}
|
||||
myEvaluationPanel.getWatchTree().rebuild(getDebuggerContext());
|
||||
descriptor.myIsExpanded = true;
|
||||
}
|
||||
finally {
|
||||
setOKActionEnabled(true);
|
||||
}
|
||||
getEditor().addRecent(getCodeToEvaluate());
|
||||
|
||||
final DebuggerSession session = myEvaluationPanel.getContextManager().getContext().getDebuggerSession();
|
||||
if (session != null) {
|
||||
session.refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected TextWithImports getCodeToEvaluate() {
|
||||
TextWithImports text = getEditor().getText();
|
||||
String s = text.getText();
|
||||
if (s != null) {
|
||||
s = s.trim();
|
||||
}
|
||||
if ("".equals(s)) {
|
||||
return null;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myEditor.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#com.intellij.debugger.ui.EvaluationDialog2";
|
||||
}
|
||||
|
||||
protected void addDisposeRunnable (Runnable runnable) {
|
||||
myDisposeRunnables.add(runnable);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for (Runnable runnable : myDisposeRunnables) {
|
||||
runnable.run();
|
||||
}
|
||||
myDisposeRunnables.clear();
|
||||
myEditor.dispose();
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getContextManager().removeListener(myContextListener);
|
||||
myEvaluationPanel.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
protected class MyEvaluationPanel extends WatchPanel {
|
||||
public MyEvaluationPanel(final Project project) {
|
||||
super(project, (DebuggerManagerEx.getInstanceEx(project)).getContextManager());
|
||||
final WatchDebuggerTree watchTree = getWatchTree();
|
||||
final AnAction setValueAction = ActionManager.getInstance().getAction(DebuggerActions.SET_VALUE);
|
||||
setValueAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), watchTree);
|
||||
registerDisposable(new Disposable() {
|
||||
public void dispose() {
|
||||
setValueAction.unregisterCustomShortcutSet(watchTree);
|
||||
}
|
||||
});
|
||||
setUpdateEnabled(true);
|
||||
getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.results"));
|
||||
new ValueNodeDnD(myTree, project);
|
||||
}
|
||||
|
||||
protected ActionPopupMenu createPopupMenu() {
|
||||
ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.EVALUATION_DIALOG_POPUP);
|
||||
return ActionManager.getInstance().createActionPopupMenu(DebuggerActions.EVALUATION_DIALOG_POPUP, group);
|
||||
}
|
||||
|
||||
protected void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event == DebuggerSession.EVENT_REFRESH || event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY) {
|
||||
// in order not to spoil the evaluation result do not re-evaluate the tree
|
||||
final TreeModel treeModel = getTree().getModel();
|
||||
updateTree(treeModel, (DebuggerTreeNodeImpl)treeModel.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTree(final TreeModel model, final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (node.getDescriptor().myIsExpanded) {
|
||||
final int count = model.getChildCount(node);
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
final DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)model.getChild(node, idx);
|
||||
updateTree(model, child);
|
||||
}
|
||||
}
|
||||
node.labelChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setDebuggerContext(DebuggerContextImpl context) {
|
||||
final PsiElement contextElement = PositionUtil.getContextElement(context);
|
||||
myEditor.setContext(contextElement);
|
||||
}
|
||||
|
||||
protected PsiElement getContext() {
|
||||
return myEditor.getContext();
|
||||
}
|
||||
|
||||
protected void initDialogData(TextWithImports text) {
|
||||
getEditor().setText(text);
|
||||
myEvaluationPanel.clear();
|
||||
}
|
||||
|
||||
public DebuggerContextImpl getDebuggerContext() {
|
||||
return DebuggerManagerEx.getInstanceEx(myProject).getContext();
|
||||
}
|
||||
|
||||
public DebuggerEditorImpl getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
protected abstract DebuggerEditorImpl createEditor(final CodeFragmentFactory factory);
|
||||
|
||||
protected MyEvaluationPanel getEvaluationPanel() {
|
||||
return myEvaluationPanel;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: May 28, 2003
|
||||
* Time: 1:59:27 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public interface EvaluatorRunnable extends Runnable{
|
||||
Object getValue();
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Dec 14, 2001
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.HelpID;
|
||||
import com.intellij.debugger.actions.ThreadDumpAction;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class ExportDialog extends DialogWrapper {
|
||||
private final JTextArea myTextArea = new JTextArea();
|
||||
private TextFieldWithBrowseButton myTfFilePath;
|
||||
private final Project myProject;
|
||||
private final DebugProcessImpl myDebugProcess;
|
||||
private final CopyToClipboardAction myCopyToClipboardAction = new CopyToClipboardAction();
|
||||
private static final @NonNls String DEFAULT_REPORT_FILE_NAME = "threads_report.txt";
|
||||
|
||||
public ExportDialog(DebugProcessImpl debugProcess, String destinationDirectory) {
|
||||
super(debugProcess.getProject(), true);
|
||||
myDebugProcess = debugProcess;
|
||||
myProject = debugProcess.getProject();
|
||||
setTitle(DebuggerBundle.message("threads.export.dialog.title"));
|
||||
setOKButtonText(DebuggerBundle.message("button.save"));
|
||||
|
||||
init();
|
||||
|
||||
setOKActionEnabled(false);
|
||||
myCopyToClipboardAction.setEnabled(false);
|
||||
|
||||
myTextArea.setText(MessageDescriptor.EVALUATING.getLabel());
|
||||
debugProcess.getManagerThread().invoke(new ExportThreadsCommand(ApplicationManager.getApplication().getModalityStateForComponent(myTextArea)));
|
||||
|
||||
myTfFilePath.setText(destinationDirectory + File.separator + DEFAULT_REPORT_FILE_NAME);
|
||||
setHorizontalStretch(1.5f);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions(){
|
||||
return new Action[]{getOKAction(), myCopyToClipboardAction, getCancelAction(), getHelpAction()};
|
||||
}
|
||||
|
||||
protected void doHelpAction() {
|
||||
HelpManager.getInstance().invokeHelp(HelpID.EXPORT_THREADS);
|
||||
}
|
||||
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel box = new JPanel(new BorderLayout());
|
||||
box.add(new JLabel(DebuggerBundle.message("label.threads.export.dialog.file")), BorderLayout.WEST);
|
||||
myTfFilePath = new TextFieldWithBrowseButton();
|
||||
myTfFilePath.addBrowseFolderListener(null, null, myProject, FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor());
|
||||
box.add(myTfFilePath, BorderLayout.CENTER);
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(box, BorderLayout.CENTER);
|
||||
panel.add(Box.createVerticalStrut(7), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
myTextArea.setEditable(false);
|
||||
JScrollPane pane = ScrollPaneFactory.createScrollPane(myTextArea);
|
||||
pane.setPreferredSize(JBUI.size(400, 300));
|
||||
return pane;
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
String path = myTfFilePath.getText();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory()) {
|
||||
Messages.showMessageDialog(
|
||||
myProject,
|
||||
DebuggerBundle.message("error.threads.export.dialog.file.is.directory"),
|
||||
DebuggerBundle.message("threads.export.dialog.title"),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
}
|
||||
else if (file.exists()) {
|
||||
int answer = Messages.showYesNoDialog(
|
||||
myProject,
|
||||
DebuggerBundle.message("error.threads.export.dialog.file.already.exists", path),
|
||||
DebuggerBundle.message("threads.export.dialog.title"),
|
||||
Messages.getQuestionIcon()
|
||||
);
|
||||
if (answer == Messages.YES) {
|
||||
super.doOKAction();
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.doOKAction();
|
||||
}
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return myTfFilePath.getText();
|
||||
}
|
||||
|
||||
public String getTextToSave() {
|
||||
return myTextArea.getText();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey(){
|
||||
return "#com.intellij.debugger.ui.ExportDialog";
|
||||
}
|
||||
|
||||
public static String getExportThreadsText(VirtualMachineProxyImpl vmProxy) {
|
||||
final StringBuffer buffer = new StringBuffer(512);
|
||||
List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads();
|
||||
for (ThreadReference threadReference : threads) {
|
||||
final String name = threadName(threadReference);
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
buffer.append(name);
|
||||
ReferenceType referenceType = threadReference.referenceType();
|
||||
if (referenceType != null) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
Field daemon = referenceType.fieldByName("daemon");
|
||||
if (daemon != null) {
|
||||
Value value = threadReference.getValue(daemon);
|
||||
if (value instanceof BooleanValue && ((BooleanValue)value).booleanValue()) {
|
||||
buffer.append(" ").append(DebuggerBundle.message("threads.export.attribute.label.daemon"));
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection HardCodedStringLiteral
|
||||
Field priority = referenceType.fieldByName("priority");
|
||||
if (priority != null) {
|
||||
Value value = threadReference.getValue(priority);
|
||||
if (value instanceof IntegerValue) {
|
||||
buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.priority", ((IntegerValue)value).intValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadGroupReference groupReference = threadReference.threadGroup();
|
||||
if (groupReference != null) {
|
||||
buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.group", groupReference.name()));
|
||||
}
|
||||
buffer.append(", ").append(
|
||||
DebuggerBundle.message("threads.export.attribute.label.status", DebuggerUtilsEx.getThreadStatusText(threadReference.status())));
|
||||
|
||||
try {
|
||||
if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) {
|
||||
List<ObjectReference> list = threadReference.ownedMonitors();
|
||||
for (ObjectReference reference : list) {
|
||||
final List<ThreadReference> waiting = reference.waitingThreads();
|
||||
for (ThreadReference thread : waiting) {
|
||||
final String waitingThreadName = threadName(thread);
|
||||
if (waitingThreadName != null) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", waitingThreadName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectReference waitedMonitor = vmProxy.canGetCurrentContendedMonitor() ? threadReference.currentContendedMonitor() : null;
|
||||
if (waitedMonitor != null) {
|
||||
if (vmProxy.canGetMonitorInfo()) {
|
||||
ThreadReference waitedThread = waitedMonitor.owningThread();
|
||||
if (waitedThread != null) {
|
||||
final String waitedThreadName = threadName(waitedThread);
|
||||
if (waitedThreadName != null) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", waitedThreadName,
|
||||
ThreadDumpAction.renderObject(waitedMonitor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<StackFrame> frames = threadReference.frames();
|
||||
for (StackFrame stackFrame : frames) {
|
||||
final Location location = stackFrame.location();
|
||||
buffer.append("\n\t ").append(renderLocation(location));
|
||||
}
|
||||
}
|
||||
catch (IncompatibleThreadStateException e) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state"));
|
||||
}
|
||||
buffer.append("\n\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static String renderLocation(final Location location) {
|
||||
String sourceName;
|
||||
try {
|
||||
sourceName = location.sourceName();
|
||||
}
|
||||
catch (AbsentInformationException e) {
|
||||
sourceName = "Unknown Source";
|
||||
}
|
||||
return DebuggerBundle.message(
|
||||
"export.threads.stackframe.format",
|
||||
DebuggerUtilsEx.getLocationMethodQName(location),
|
||||
sourceName,
|
||||
location.lineNumber()
|
||||
);
|
||||
}
|
||||
|
||||
private static String threadName(ThreadReference threadReference) {
|
||||
try {
|
||||
return threadReference.name() + "@" + threadReference.uniqueID();
|
||||
}
|
||||
catch (ObjectCollectedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class CopyToClipboardAction extends AbstractAction {
|
||||
public CopyToClipboardAction() {
|
||||
super(DebuggerBundle.message("button.copy"));
|
||||
putValue(Action.SHORT_DESCRIPTION, DebuggerBundle.message("export.dialog.copy.action.description"));
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String s = StringUtil.convertLineSeparators(myTextArea.getText());
|
||||
CopyPasteManager.getInstance().setContents(new StringSelection(s));
|
||||
}
|
||||
}
|
||||
|
||||
private class ExportThreadsCommand extends DebuggerCommandImpl {
|
||||
protected ModalityState myModalityState;
|
||||
|
||||
public ExportThreadsCommand(ModalityState modalityState) {
|
||||
myModalityState = modalityState;
|
||||
}
|
||||
|
||||
private void setText(final String text) {
|
||||
DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTextArea.setText(text);
|
||||
setOKActionEnabled(true);
|
||||
myCopyToClipboardAction.setEnabled(true);
|
||||
}
|
||||
}, myModalityState);
|
||||
}
|
||||
|
||||
protected void action() {
|
||||
setText(getExportThreadsText(myDebugProcess.getVirtualMachineProxy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,732 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.SuspendManagerUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.engine.jdi.StackFrameProxy;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextUtil;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.debugger.ui.impl.DebuggerComboBoxRenderer;
|
||||
import com.intellij.debugger.ui.impl.FramesList;
|
||||
import com.intellij.debugger.ui.impl.UpdatableDebuggerView;
|
||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker;
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.CommonActionsManager;
|
||||
import com.intellij.ide.OccurenceNavigator;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComboBoxWithWidePopup;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.CaptionPanel;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.border.CustomLineBorder;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.sun.jdi.ObjectCollectedException;
|
||||
import com.sun.jdi.VMDisconnectedException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class FramesPanel extends UpdatableDebuggerView implements DataProvider {
|
||||
private static final Icon FILTER_STACK_FRAMES_ICON = AllIcons.Debugger.Class_filter;
|
||||
|
||||
private final JComboBox myThreadsCombo;
|
||||
private final FramesList myFramesList;
|
||||
private final ThreadsListener myThreadsListener;
|
||||
private final FramesListener myFramesListener;
|
||||
private final DebuggerStateManager myStateManager;
|
||||
private boolean myShowLibraryFrames = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
|
||||
private final Alarm myRebuildAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
|
||||
public FramesPanel(Project project, DebuggerStateManager stateManager) {
|
||||
super(project, stateManager);
|
||||
myStateManager = stateManager;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
myThreadsCombo = new ComboBoxWithWidePopup();
|
||||
myThreadsCombo.setRenderer(new DebuggerComboBoxRenderer(myThreadsCombo.getRenderer()));
|
||||
myThreadsListener = new ThreadsListener();
|
||||
myThreadsCombo.addItemListener(myThreadsListener);
|
||||
|
||||
myFramesList = new FramesList(project);
|
||||
myFramesListener = new FramesListener();
|
||||
myFramesList.addListSelectionListener(myFramesListener);
|
||||
|
||||
myFramesList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
int index = myFramesList.locationToIndex(e.getPoint());
|
||||
if (index >= 0 && myFramesList.isSelectedIndex(index)) {
|
||||
processListValue(myFramesList.getModel().getElementAt(index));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerThreadsPopupMenu(myFramesList);
|
||||
|
||||
setBorder(null);
|
||||
|
||||
final ActionToolbar toolbar = createToolbar();
|
||||
Wrapper threads = new Wrapper();
|
||||
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, 1, 0);
|
||||
threads.setBorder(border);
|
||||
threads.add(toolbar.getComponent(), BorderLayout.EAST);
|
||||
threads.add(myThreadsCombo, BorderLayout.CENTER);
|
||||
add(threads, BorderLayout.NORTH);
|
||||
add(ScrollPaneFactory.createScrollPane(myFramesList), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private ActionToolbar createToolbar() {
|
||||
final DefaultActionGroup framesGroup = new DefaultActionGroup();
|
||||
framesGroup.addSeparator();
|
||||
|
||||
CommonActionsManager actionsManager = CommonActionsManager.getInstance();
|
||||
framesGroup.add(actionsManager.createPrevOccurenceAction(getOccurenceNavigator()));
|
||||
framesGroup.add(actionsManager.createNextOccurenceAction(getOccurenceNavigator()));
|
||||
framesGroup.add(new ShowLibraryFramesAction());
|
||||
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.DEBUGGER_TOOLBAR, framesGroup, true);
|
||||
toolbar.setReservePlaceAutoPopupIcon(false);
|
||||
((ActionToolbarImpl)toolbar).setAddSeparatorFirst(true);
|
||||
toolbar.getComponent().setBorder(new EmptyBorder(1, 0, 0, 0));
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebuggerStateManager getContextManager() {
|
||||
return myStateManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (CommonDataKeys.PSI_FILE.is(dataId)) {
|
||||
DebuggerContextImpl context = myStateManager.getContext();
|
||||
if (context != null) {
|
||||
SourcePosition position = context.getSourcePosition();
|
||||
if (position != null) {
|
||||
return position.getFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FramesListener implements ListSelectionListener {
|
||||
boolean myIsEnabled = true;
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
myIsEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (!myIsEnabled || e.getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
final JList list = (JList)e.getSource();
|
||||
processListValue(list.getSelectedValue());
|
||||
}
|
||||
|
||||
}
|
||||
private void processListValue(final Object selected) {
|
||||
if (selected instanceof StackFrameDescriptorImpl) {
|
||||
DebuggerContextUtil.setStackFrame(getContextManager(), ((StackFrameDescriptorImpl)selected).getFrameProxy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void registerThreadsPopupMenu(final JList framesList) {
|
||||
final PopupHandler popupHandler = new PopupHandler() {
|
||||
@Override
|
||||
public void invokePopup(Component comp, int x, int y) {
|
||||
DefaultActionGroup group = (DefaultActionGroup)ActionManager.getInstance().getAction(DebuggerActions.THREADS_PANEL_POPUP);
|
||||
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.THREADS_PANEL_POPUP, group);
|
||||
popupMenu.getComponent().show(comp, x, y);
|
||||
}
|
||||
};
|
||||
framesList.addMouseListener(popupHandler);
|
||||
registerDisposable(new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myThreadsCombo.removeItemListener(myThreadsListener);
|
||||
framesList.removeMouseListener(popupHandler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ThreadsListener implements ItemListener {
|
||||
boolean myIsEnabled = true;
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
myIsEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (!myIsEnabled) return;
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
ThreadDescriptorImpl item = (ThreadDescriptorImpl)e.getItem();
|
||||
DebuggerContextUtil.setThread(getContextManager(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final AtomicBoolean myPerformFullRebuild = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
protected void rebuild(int event) {
|
||||
myRebuildAlarm.cancelAllRequests();
|
||||
final boolean isRefresh = event == DebuggerSession.EVENT_REFRESH ||
|
||||
event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY ||
|
||||
event == DebuggerSession.EVENT_THREADS_REFRESH;
|
||||
if (!isRefresh) {
|
||||
myPerformFullRebuild.set(true);
|
||||
}
|
||||
myRebuildAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
doRebuild(!myPerformFullRebuild.getAndSet(false));
|
||||
}
|
||||
catch (VMDisconnectedException ignored) {
|
||||
}
|
||||
}
|
||||
}, 100, ModalityState.NON_MODAL);
|
||||
}
|
||||
|
||||
private void doRebuild(boolean refreshOnly) {
|
||||
final DebuggerContextImpl context = getContext();
|
||||
final DebuggerSession session = context.getDebuggerSession();
|
||||
final boolean paused = session != null && session.isPaused();
|
||||
if (!paused || !refreshOnly) {
|
||||
myThreadsCombo.removeAllItems();
|
||||
synchronized (myFramesList) {
|
||||
myFramesLastUpdateTime = getNextStamp();
|
||||
myFramesList.getModel().clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (paused) {
|
||||
final DebugProcessImpl process = context.getDebugProcess();
|
||||
if (process != null) {
|
||||
process.getManagerThread().schedule(new RefreshFramePanelCommand(refreshOnly && myThreadsCombo.getItemCount() != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
Disposer.dispose(myRebuildAlarm);
|
||||
}
|
||||
finally {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowLibraryFrames() {
|
||||
return myShowLibraryFrames;
|
||||
}
|
||||
|
||||
public void setShowLibraryFrames(boolean showLibraryFrames) {
|
||||
if (myShowLibraryFrames != showLibraryFrames) {
|
||||
myShowLibraryFrames = showLibraryFrames;
|
||||
rebuild(DebuggerSession.EVENT_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
private class RefreshFramePanelCommand extends DebuggerContextCommandImpl {
|
||||
private final boolean myRefreshOnly;
|
||||
private final ThreadDescriptorImpl[] myThreadDescriptorsToUpdate;
|
||||
|
||||
public RefreshFramePanelCommand(final boolean refreshOnly) {
|
||||
super(getContext());
|
||||
myRefreshOnly = refreshOnly;
|
||||
if (refreshOnly) {
|
||||
final int size = myThreadsCombo.getItemCount();
|
||||
myThreadDescriptorsToUpdate = new ThreadDescriptorImpl[size];
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
myThreadDescriptorsToUpdate[idx] = (ThreadDescriptorImpl)myThreadsCombo.getItemAt(idx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myThreadDescriptorsToUpdate = null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ThreadDescriptorImpl> createThreadDescriptorsList() {
|
||||
final List<ThreadReferenceProxyImpl> threads = new ArrayList<ThreadReferenceProxyImpl>(getSuspendContext().getDebugProcess().getVirtualMachineProxy().allThreads());
|
||||
Collections.sort(threads, ThreadReferenceProxyImpl.ourComparator);
|
||||
|
||||
final List<ThreadDescriptorImpl> descriptors = new ArrayList<ThreadDescriptorImpl>(threads.size());
|
||||
EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext();
|
||||
|
||||
for (ThreadReferenceProxyImpl thread : threads) {
|
||||
ThreadDescriptorImpl threadDescriptor = new ThreadDescriptorImpl(thread);
|
||||
threadDescriptor.setContext(evaluationContext);
|
||||
threadDescriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
descriptors.add(threadDescriptor);
|
||||
}
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadAction() {
|
||||
if (myRefreshOnly && myThreadDescriptorsToUpdate.length != myThreadsCombo.getItemCount()) {
|
||||
// there is no sense in refreshing combobox if thread list has changed since creation of this command
|
||||
return;
|
||||
}
|
||||
|
||||
final DebuggerContextImpl context = getDebuggerContext();
|
||||
|
||||
final ThreadReferenceProxyImpl threadToSelect = context.getThreadProxy();
|
||||
if(threadToSelect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(context.getSuspendContext(), threadToSelect);
|
||||
final ThreadDescriptorImpl currentThreadDescriptor = (ThreadDescriptorImpl)myThreadsCombo.getSelectedItem();
|
||||
final ThreadReferenceProxyImpl currentThread = currentThreadDescriptor != null? currentThreadDescriptor.getThreadReference() : null;
|
||||
|
||||
if (myRefreshOnly && threadToSelect.equals(currentThread)) {
|
||||
context.getDebugProcess().getManagerThread().schedule(new UpdateFramesListCommand(context, threadContext));
|
||||
}
|
||||
else {
|
||||
context.getDebugProcess().getManagerThread().schedule(new RebuildFramesListCommand(context, threadContext));
|
||||
}
|
||||
|
||||
if (myRefreshOnly) {
|
||||
final EvaluationContextImpl evaluationContext = context.createEvaluationContext();
|
||||
for (ThreadDescriptorImpl descriptor : myThreadDescriptorsToUpdate) {
|
||||
descriptor.setContext(evaluationContext);
|
||||
descriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
}
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myThreadsListener.setEnabled(false);
|
||||
selectThread(threadToSelect);
|
||||
myFramesList.repaint();
|
||||
}
|
||||
finally {
|
||||
myThreadsListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else { // full rebuild
|
||||
refillThreadsCombo(threadToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commandCancelled() {
|
||||
if (!DebuggerManagerThreadImpl.isManagerThread()) {
|
||||
return;
|
||||
}
|
||||
// context thread is not suspended
|
||||
final DebuggerContextImpl context = getDebuggerContext();
|
||||
|
||||
final SuspendContextImpl suspendContext = context.getSuspendContext();
|
||||
if (suspendContext == null) {
|
||||
return;
|
||||
}
|
||||
final ThreadReferenceProxyImpl threadToSelect = context.getThreadProxy();
|
||||
if(threadToSelect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!suspendContext.isResumed()) {
|
||||
final SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(suspendContext, threadToSelect);
|
||||
context.getDebugProcess().getManagerThread().schedule(new RebuildFramesListCommand(context, threadContext));
|
||||
refillThreadsCombo(threadToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
private void refillThreadsCombo(final ThreadReferenceProxyImpl threadToSelect) {
|
||||
final List<ThreadDescriptorImpl> threadItems = createThreadDescriptorsList();
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myThreadsListener.setEnabled(false);
|
||||
|
||||
myThreadsCombo.removeAllItems();
|
||||
for (final ThreadDescriptorImpl threadItem : threadItems) {
|
||||
myThreadsCombo.addItem(threadItem);
|
||||
}
|
||||
|
||||
selectThread(threadToSelect);
|
||||
}
|
||||
finally {
|
||||
myThreadsListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateFramesListCommand extends SuspendContextCommandImpl {
|
||||
private final DebuggerContextImpl myDebuggerContext;
|
||||
|
||||
public UpdateFramesListCommand(DebuggerContextImpl debuggerContext, SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
myDebuggerContext = debuggerContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
updateFrameList(myDebuggerContext.getThreadProxy());
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
final StackFrameProxyImpl contextFrame = getDebuggerContext().getFrameProxy();
|
||||
if(contextFrame != null) {
|
||||
selectFrame(contextFrame);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void updateFrameList(ThreadReferenceProxyImpl thread) {
|
||||
try {
|
||||
if(!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ObjectCollectedException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext();
|
||||
final List<StackFrameDescriptorImpl> descriptors = new ArrayList<StackFrameDescriptorImpl>();
|
||||
|
||||
synchronized (myFramesList) {
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
final int size = model.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Object elem = model.getElementAt(i);
|
||||
if (elem instanceof StackFrameDescriptorImpl) {
|
||||
descriptors.add((StackFrameDescriptorImpl)elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (StackFrameDescriptorImpl descriptor : descriptors) {
|
||||
descriptor.setContext(evaluationContext);
|
||||
descriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
public DebuggerContextImpl getDebuggerContext() {
|
||||
return myDebuggerContext;
|
||||
}
|
||||
}
|
||||
|
||||
private class RebuildFramesListCommand extends SuspendContextCommandImpl {
|
||||
private final DebuggerContextImpl myDebuggerContext;
|
||||
|
||||
public RebuildFramesListCommand(DebuggerContextImpl debuggerContext, SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
myDebuggerContext = debuggerContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
final ThreadReferenceProxyImpl thread = myDebuggerContext.getThreadProxy();
|
||||
try {
|
||||
if(!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
synchronized (myFramesList) {
|
||||
myFramesLastUpdateTime = getNextStamp();
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
model.clear();
|
||||
model.addElement(new Object() {
|
||||
public String toString() {
|
||||
return DebuggerBundle.message("frame.panel.frames.not.available");
|
||||
}
|
||||
});
|
||||
myFramesList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ObjectCollectedException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<StackFrameProxyImpl> frames;
|
||||
try {
|
||||
frames = thread.frames();
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
frames = Collections.emptyList();
|
||||
}
|
||||
|
||||
final StackFrameProxyImpl contextFrame = myDebuggerContext.getFrameProxy();
|
||||
final EvaluationContextImpl evaluationContext = myDebuggerContext.createEvaluationContext();
|
||||
final DebuggerManagerThreadImpl managerThread = myDebuggerContext.getDebugProcess().getManagerThread();
|
||||
final MethodsTracker tracker = new MethodsTracker();
|
||||
final int totalFramesCount = frames.size();
|
||||
int index = 0;
|
||||
final IndexCounter indexCounter = new IndexCounter(totalFramesCount);
|
||||
final long timestamp = getNextStamp();
|
||||
for (StackFrameProxyImpl stackFrameProxy : frames) {
|
||||
managerThread.schedule(
|
||||
new AppendFrameCommand(
|
||||
getSuspendContext(),
|
||||
stackFrameProxy,
|
||||
evaluationContext,
|
||||
tracker,
|
||||
index++,
|
||||
stackFrameProxy.equals(contextFrame),
|
||||
timestamp,
|
||||
indexCounter
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void selectThread(ThreadReferenceProxyImpl toSelect) {
|
||||
int count = myThreadsCombo.getItemCount();
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
ThreadDescriptorImpl item = (ThreadDescriptorImpl)myThreadsCombo.getItemAt(idx);
|
||||
if (toSelect.equals(item.getThreadReference())) {
|
||||
if (!item.equals(myThreadsCombo.getSelectedItem())) {
|
||||
myThreadsCombo.setSelectedIndex(idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*invoked in swing thread*/
|
||||
private void selectFrame(StackFrameProxy frame) {
|
||||
synchronized (myFramesList) {
|
||||
final int count = myFramesList.getElementCount();
|
||||
final Object selectedValue = myFramesList.getSelectedValue();
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
final Object elem = model.getElementAt(idx);
|
||||
if (elem instanceof StackFrameDescriptorImpl) {
|
||||
final StackFrameDescriptorImpl item = (StackFrameDescriptorImpl)elem;
|
||||
if (frame.equals(item.getFrameProxy())) {
|
||||
if (!item.equals(selectedValue)) {
|
||||
myFramesList.setSelectedIndex(idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class IndexCounter {
|
||||
private final int[] myData;
|
||||
|
||||
private IndexCounter(int totalSize) {
|
||||
myData = new int[totalSize];
|
||||
for (int idx = 0; idx < totalSize; idx++) {
|
||||
myData[idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void markCalculated(int idx){
|
||||
myData[idx] = 1;
|
||||
}
|
||||
|
||||
public int getActualIndex(final int index) {
|
||||
int result = 0;
|
||||
for (int idx = 0; idx < index; idx++) {
|
||||
result += myData[idx];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final AtomicLong myTimeCounter = new AtomicLong(0L);
|
||||
private long getNextStamp() {
|
||||
return myTimeCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
private long myFramesLastUpdateTime = 0L;
|
||||
|
||||
private class AppendFrameCommand extends SuspendContextCommandImpl {
|
||||
private final StackFrameProxyImpl myFrame;
|
||||
private final EvaluationContextImpl myEvaluationContext;
|
||||
private final MethodsTracker myTracker;
|
||||
private final int myIndexToInsert;
|
||||
private final boolean myIsContextFrame;
|
||||
private final long myTimestamp;
|
||||
private final IndexCounter myCounter;
|
||||
|
||||
public AppendFrameCommand(@NotNull SuspendContextImpl suspendContext, @NotNull StackFrameProxyImpl frame, EvaluationContextImpl evaluationContext,
|
||||
MethodsTracker tracker, int indexToInsert, final boolean isContextFrame, final long timestamp, IndexCounter counter) {
|
||||
super(suspendContext);
|
||||
myFrame = frame;
|
||||
myEvaluationContext = evaluationContext;
|
||||
myTracker = tracker;
|
||||
myIndexToInsert = indexToInsert;
|
||||
myIsContextFrame = isContextFrame;
|
||||
myTimestamp = timestamp;
|
||||
myCounter = counter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
final StackFrameDescriptorImpl descriptor = new StackFrameDescriptorImpl(myFrame, myTracker);
|
||||
descriptor.setContext(myEvaluationContext);
|
||||
descriptor.updateRepresentation(myEvaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
final Project project = getProject();
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
synchronized (myFramesList) {
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
if (myFramesLastUpdateTime < myTimestamp) {
|
||||
myFramesLastUpdateTime = myTimestamp;
|
||||
model.clear();
|
||||
}
|
||||
if (myTimestamp != myFramesLastUpdateTime) {
|
||||
return; // the command has expired
|
||||
}
|
||||
final boolean shouldHide = !myShowLibraryFrames && !myIsContextFrame && myIndexToInsert != 0 && (descriptor.isSynthetic() || descriptor.isInLibraryContent());
|
||||
if (!shouldHide) {
|
||||
myCounter.markCalculated(myIndexToInsert);
|
||||
final int actualIndex = myCounter.getActualIndex(myIndexToInsert);
|
||||
model.insertElementAt(descriptor, actualIndex);
|
||||
if (myIsContextFrame) {
|
||||
myFramesList.setSelectedIndex(actualIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
myFramesList.requestFocus();
|
||||
}
|
||||
|
||||
public OccurenceNavigator getOccurenceNavigator() {
|
||||
return myFramesList;
|
||||
}
|
||||
|
||||
public FramesList getFramesList() {
|
||||
return myFramesList;
|
||||
}
|
||||
|
||||
private class ShowLibraryFramesAction extends ToggleAction {
|
||||
private volatile boolean myShouldShow;
|
||||
private static final String ourTextWhenShowIsOn = "Hide Frames from Libraries";
|
||||
private static final String ourTextWhenShowIsOff = "Show All Frames";
|
||||
|
||||
public ShowLibraryFramesAction() {
|
||||
super("", "", FILTER_STACK_FRAMES_ICON);
|
||||
myShouldShow = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
final boolean shouldShow = !Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY));
|
||||
presentation.setText(shouldShow ? ourTextWhenShowIsOn : ourTextWhenShowIsOff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return !myShouldShow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean enabled) {
|
||||
myShouldShow = !enabled;
|
||||
DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES = myShouldShow;
|
||||
setShowLibraryFrames(myShouldShow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.DebugProcessEvents;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.impl.*;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.ui.breakpoints.*;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.event.Event;
|
||||
import com.sun.jdi.event.LocatableEvent;
|
||||
import com.sun.jdi.event.MethodEntryEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: Jul 9, 2003
|
||||
* Time: 6:24:35 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class PositionHighlighter {
|
||||
private static final Key<Boolean> HIGHLIGHTER_USERDATA_KEY = new Key<Boolean>("HIGHLIGHTER_USERDATA_KEY");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.PositionHighlighter");
|
||||
private final Project myProject;
|
||||
private DebuggerContextImpl myContext = DebuggerContextImpl.EMPTY_CONTEXT;
|
||||
private SelectionDescription mySelectionDescription = null;
|
||||
private ExecutionPointDescription myExecutionPointDescription = null;
|
||||
|
||||
public PositionHighlighter(Project project, DebuggerStateManager stateManager) {
|
||||
myProject = project;
|
||||
|
||||
stateManager.addListener(new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
myContext = newContext;
|
||||
if (event != DebuggerSession.EVENT_REFRESH_VIEWS_ONLY && event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showLocationInEditor() {
|
||||
myContext.getDebugProcess().getManagerThread().schedule(new ShowLocationCommand(myContext));
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
clearSelections();
|
||||
final DebuggerSession session = myContext.getDebuggerSession();
|
||||
if(session != null) {
|
||||
switch(session.getState()) {
|
||||
case DebuggerSession.STATE_PAUSED:
|
||||
if(myContext.getFrameProxy() != null) {
|
||||
showLocationInEditor();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ExecutionPointDescription extends SelectionDescription {
|
||||
private RangeHighlighter myHighlighter;
|
||||
private final int myLineIndex;
|
||||
|
||||
protected ExecutionPointDescription(Editor editor, int lineIndex) {
|
||||
super(editor);
|
||||
myLineIndex = lineIndex;
|
||||
}
|
||||
|
||||
public void select() {
|
||||
if(myIsActive) return;
|
||||
myIsActive = true;
|
||||
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
myHighlighter = myEditor.getMarkupModel().addLineHighlighter(
|
||||
myLineIndex,
|
||||
DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER,
|
||||
scheme.getAttributes(DebuggerColors.EXECUTIONPOINT_ATTRIBUTES)
|
||||
);
|
||||
adjustCounter(myEditor, 1);
|
||||
myHighlighter.setErrorStripeTooltip(DebuggerBundle.message("position.highlighter.stripe.tooltip"));
|
||||
myHighlighter.putUserData(HIGHLIGHTER_USERDATA_KEY, Boolean.TRUE);
|
||||
}
|
||||
|
||||
private static void adjustCounter(@NotNull Editor editor, int increment) {
|
||||
JComponent component = editor.getComponent();
|
||||
Object o = component.getClientProperty(EditorImpl.IGNORE_MOUSE_TRACKING);
|
||||
Integer value = ((o instanceof Integer) ? (Integer)o : 0) + increment;
|
||||
component.putClientProperty(EditorImpl.IGNORE_MOUSE_TRACKING, value > 0 ? value : null);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if(!myIsActive) return;
|
||||
myIsActive = false;
|
||||
adjustCounter(myEditor, -1);
|
||||
if (myHighlighter != null) {
|
||||
myHighlighter.dispose();
|
||||
myHighlighter = null;
|
||||
}
|
||||
}
|
||||
|
||||
public RangeHighlighter getHighlighter() {
|
||||
return myHighlighter;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract static class SelectionDescription {
|
||||
protected Editor myEditor;
|
||||
protected boolean myIsActive;
|
||||
|
||||
public SelectionDescription(Editor editor) {
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
public abstract void select();
|
||||
public abstract void remove();
|
||||
|
||||
public static ExecutionPointDescription createExecutionPoint(final Editor editor,
|
||||
final int lineIndex) {
|
||||
return new ExecutionPointDescription(editor, lineIndex);
|
||||
}
|
||||
|
||||
public static SelectionDescription createSelection(final Editor editor, final int lineIndex) {
|
||||
return new SelectionDescription(editor) {
|
||||
public void select() {
|
||||
if(myIsActive) return;
|
||||
myIsActive = true;
|
||||
DocumentEx doc = (DocumentEx)editor.getDocument();
|
||||
editor.getSelectionModel().setSelection(
|
||||
doc.getLineStartOffset(lineIndex),
|
||||
doc.getLineEndOffset(lineIndex) + doc.getLineSeparatorLength(lineIndex)
|
||||
);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if(!myIsActive) return;
|
||||
myIsActive = false;
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void showSelection(SourcePosition position) {
|
||||
Editor editor = getEditor(position);
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
if (mySelectionDescription != null) {
|
||||
mySelectionDescription.remove();
|
||||
}
|
||||
mySelectionDescription = SelectionDescription.createSelection(editor, position.getLine());
|
||||
mySelectionDescription.select();
|
||||
}
|
||||
|
||||
private void showExecutionPoint(final SourcePosition position, List<Pair<Breakpoint, Event>> events) {
|
||||
if (myExecutionPointDescription != null) {
|
||||
myExecutionPointDescription.remove();
|
||||
}
|
||||
int lineIndex = position.getLine();
|
||||
Editor editor = getEditor(position);
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
myExecutionPointDescription = SelectionDescription.createExecutionPoint(editor, lineIndex);
|
||||
myExecutionPointDescription.select();
|
||||
|
||||
RangeHighlighter highlighter = myExecutionPointDescription.getHighlighter();
|
||||
|
||||
if(highlighter != null) {
|
||||
final List<Pair<Breakpoint, Event>> eventsOutOfLine = new ArrayList<Pair<Breakpoint, Event>>();
|
||||
|
||||
for (final Pair<Breakpoint, Event> eventDescriptor : events) {
|
||||
final Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
// filter breakpoints that do not match the event
|
||||
if (breakpoint instanceof MethodBreakpoint) {
|
||||
try {
|
||||
if (!((MethodBreakpoint)breakpoint).matchesEvent((LocatableEvent)eventDescriptor.getSecond(), myContext.getDebugProcess())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
}
|
||||
else if (breakpoint instanceof WildcardMethodBreakpoint) {
|
||||
if (!((WildcardMethodBreakpoint)breakpoint).matchesEvent((LocatableEvent)eventDescriptor.getSecond())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (breakpoint instanceof BreakpointWithHighlighter) {
|
||||
if (((BreakpointWithHighlighter)breakpoint).isVisible() && breakpoint.isValid()) {
|
||||
breakpoint.reload();
|
||||
int bptLine = ((BreakpointWithHighlighter)breakpoint).getLineIndex();
|
||||
if (bptLine < 0 || bptLine != lineIndex) {
|
||||
eventsOutOfLine.add(eventDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
eventsOutOfLine.add(eventDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if(!eventsOutOfLine.isEmpty()) {
|
||||
highlighter.setGutterIconRenderer(new MyGutterIconRenderer(eventsOutOfLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Editor getEditor(SourcePosition position) {
|
||||
final PsiFile psiFile = position.getFile();
|
||||
Document doc = PsiDocumentManager.getInstance(myProject).getDocument(psiFile);
|
||||
if (!psiFile.isValid()) {
|
||||
return null;
|
||||
}
|
||||
final int lineIndex = position.getLine();
|
||||
if (lineIndex < 0 || lineIndex > doc.getLineCount()) {
|
||||
//LOG.assertTrue(false, "Incorrect lineIndex " + lineIndex + " in file " + psiFile.getName());
|
||||
return null;
|
||||
}
|
||||
return position.openEditor(false);
|
||||
}
|
||||
|
||||
private void clearSelections() {
|
||||
if (mySelectionDescription != null || myExecutionPointDescription != null) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
if (mySelectionDescription != null) {
|
||||
mySelectionDescription.remove();
|
||||
mySelectionDescription = null;
|
||||
}
|
||||
if (myExecutionPointDescription != null) {
|
||||
myExecutionPointDescription.remove();
|
||||
myExecutionPointDescription = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateContextPointDescription() {
|
||||
if(myContext.getDebuggerSession() == null) return;
|
||||
|
||||
showLocationInEditor();
|
||||
}
|
||||
|
||||
private class ShowLocationCommand extends DebuggerContextCommandImpl {
|
||||
private final DebuggerContextImpl myContext;
|
||||
|
||||
public ShowLocationCommand(DebuggerContextImpl context) {
|
||||
super(context);
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
public void threadAction() {
|
||||
final SourcePosition contextPosition = myContext.getSourcePosition();
|
||||
if (contextPosition == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isExecutionPoint = false;
|
||||
try {
|
||||
StackFrameProxyImpl frameProxy = myContext.getFrameProxy();
|
||||
final ThreadReferenceProxyImpl thread = getSuspendContext().getThread();
|
||||
isExecutionPoint = thread != null && frameProxy != null && frameProxy.equals(thread.frame(0));
|
||||
}
|
||||
catch(Throwable th) {
|
||||
LOG.debug(th);
|
||||
}
|
||||
|
||||
final List<Pair<Breakpoint, Event>> events = DebuggerUtilsEx.getEventDescriptors(getSuspendContext());
|
||||
|
||||
final SourcePosition position = ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
|
||||
public SourcePosition compute() {
|
||||
Document document = PsiDocumentManager.getInstance(myProject).getDocument(contextPosition.getFile());
|
||||
if(document != null) {
|
||||
if(contextPosition.getLine() < 0 || contextPosition.getLine() >= document.getLineCount()) {
|
||||
return SourcePosition.createFromLine(contextPosition.getFile(), 0);
|
||||
}
|
||||
}
|
||||
return contextPosition;
|
||||
}
|
||||
});
|
||||
|
||||
if(isExecutionPoint) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
final SourcePosition highlightPosition = getHighlightPosition(events, position);
|
||||
showExecutionPoint(highlightPosition, events);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
showSelection(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private SourcePosition getHighlightPosition(final List<Pair<Breakpoint, Event>> events, SourcePosition position) {
|
||||
for (Iterator<Pair<Breakpoint, Event>> iterator = events.iterator(); iterator.hasNext();) {
|
||||
final Pair<Breakpoint, Event> eventDescriptor = iterator.next();
|
||||
final Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
if(breakpoint instanceof LineBreakpoint) {
|
||||
breakpoint.reload();
|
||||
final SourcePosition breakPosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition();
|
||||
if(breakPosition != null && breakPosition.getLine() != position.getLine()) {
|
||||
position = SourcePosition.createFromLine(position.getFile(), breakPosition.getLine());
|
||||
}
|
||||
}
|
||||
else if(breakpoint instanceof MethodBreakpoint) {
|
||||
final MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint;
|
||||
methodBreakpoint.reload();
|
||||
final SourcePosition breakPosition = methodBreakpoint.getSourcePosition();
|
||||
final LocatableEvent event = (LocatableEvent)eventDescriptor.getSecond();
|
||||
if(breakPosition != null && breakPosition.getFile().equals(position.getFile()) && breakPosition.getLine() != position.getLine() && event instanceof MethodEntryEvent) {
|
||||
try {
|
||||
if (methodBreakpoint.matchesEvent(event, myContext.getDebugProcess())) {
|
||||
position = SourcePosition.createFromLine(position.getFile(), breakPosition.getLine());
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyGutterIconRenderer extends GutterIconRenderer {
|
||||
private final List<Pair<Breakpoint, Event>> myEventsOutOfLine;
|
||||
|
||||
public MyGutterIconRenderer(List<Pair<Breakpoint, Event>> eventsOutOfLine) {
|
||||
myEventsOutOfLine = eventsOutOfLine;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
return myEventsOutOfLine.get(0).getFirst().getIcon();
|
||||
}
|
||||
|
||||
public String getTooltipText() {
|
||||
DebugProcessImpl debugProcess = myContext.getDebugProcess();
|
||||
if (debugProcess == null) {
|
||||
return null;
|
||||
}
|
||||
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("<html><body>");
|
||||
for (Iterator<Pair<Breakpoint, Event>> iterator = myEventsOutOfLine.iterator(); iterator.hasNext();) {
|
||||
Pair<Breakpoint, Event> eventDescriptor = iterator.next();
|
||||
buf.append(((DebugProcessEvents)debugProcess).getEventText(eventDescriptor));
|
||||
if(iterator.hasNext()) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("<br>");
|
||||
}
|
||||
}
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("</body></html>");
|
||||
return buf.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
}
|
||||
}
|
||||
|
||||
public ActionGroup getPopupMenuActions() {
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
for (Pair<Breakpoint, Event> eventDescriptor : myEventsOutOfLine) {
|
||||
Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
AnAction viewBreakpointsAction = new ViewBreakpointsAction(breakpoint.getDisplayName(), breakpoint.getXBreakpoint());
|
||||
group.add(viewBreakpointsAction);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnAction getMiddleButtonClickAction() {
|
||||
return new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (myEventsOutOfLine.size() == 1) {
|
||||
Breakpoint breakpoint = myEventsOutOfLine.get(0).getFirst();
|
||||
breakpoint.setEnabled(!breakpoint.isEnabled());
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().fireBreakpointChanged(breakpoint);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof MyGutterIconRenderer &&
|
||||
Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) &&
|
||||
Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getIcon().hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.util.WeakListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 25, 2004
|
||||
*/
|
||||
public class WeakMouseListener extends WeakListener<JComponent, MouseListener> {
|
||||
public WeakMouseListener(JComponent source, MouseListener listenerImpl) {
|
||||
super(source, MouseListener.class, listenerImpl);
|
||||
}
|
||||
public void addListener(JComponent source, MouseListener listener) {
|
||||
source.addMouseListener(listener);
|
||||
}
|
||||
public void removeListener(JComponent source, MouseListener listener) {
|
||||
source.removeMouseListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.util.WeakListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 25, 2004
|
||||
*/
|
||||
public class WeakMouseMotionListener extends WeakListener<JComponent, MouseMotionListener> {
|
||||
public WeakMouseMotionListener(JComponent source, MouseMotionListener listenerImpl) {
|
||||
super(source, MouseMotionListener.class, listenerImpl);
|
||||
}
|
||||
public void addListener(JComponent source, MouseMotionListener listener) {
|
||||
source.addMouseMotionListener(listener);
|
||||
}
|
||||
public void removeListener(JComponent source, MouseMotionListener listener) {
|
||||
source.removeMouseMotionListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class DebuggerComboBoxRenderer extends ListCellRendererWrapper {
|
||||
public DebuggerComboBoxRenderer(final ListCellRenderer listCellRenderer) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (list.getComponentCount() > 0) {
|
||||
Icon icon = getIcon(value);
|
||||
if (icon != null) {
|
||||
setIcon(icon);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setIcon(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Icon getIcon(Object item) {
|
||||
if (item instanceof ThreadDescriptorImpl) {
|
||||
return ((ThreadDescriptorImpl)item).getIcon();
|
||||
}
|
||||
if (item instanceof StackFrameDescriptorImpl) {
|
||||
return ((StackFrameDescriptorImpl)item).getIcon();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.xdebugger.impl.frame.DebuggerFramesList;
|
||||
import com.sun.jdi.Method;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 7, 2006
|
||||
*/
|
||||
public class FramesList extends DebuggerFramesList {
|
||||
private volatile Method mySelectedMethod = null;
|
||||
|
||||
public FramesList(Project project) {
|
||||
super(project);
|
||||
doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FramesListRenderer createListRenderer() {
|
||||
return new FramesListRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFrameChanged(final Object selectedValue) {
|
||||
final StackFrameDescriptorImpl descriptor = selectedValue instanceof StackFrameDescriptorImpl? (StackFrameDescriptorImpl)selectedValue : null;
|
||||
final Method newMethod = descriptor != null? descriptor.getMethod() : null;
|
||||
if (!Comparing.equal(mySelectedMethod, newMethod)) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
mySelectedMethod = newMethod;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.Method;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.MatteBorder;
|
||||
import java.awt.*;
|
||||
|
||||
class FramesListRenderer extends ColoredListCellRenderer {
|
||||
private final EditorColorsScheme myColorScheme;
|
||||
|
||||
public FramesListRenderer() {
|
||||
myColorScheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customizeCellRenderer(final JList list, final Object item, final int index, final boolean selected, final boolean hasFocus) {
|
||||
if (!(item instanceof StackFrameDescriptorImpl)) {
|
||||
append(item.toString(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
final StackFrameDescriptorImpl descriptor = (StackFrameDescriptorImpl)item;
|
||||
setIcon(descriptor.getIcon());
|
||||
final Object selectedValue = list.getSelectedValue();
|
||||
final boolean shouldHighlightAsRecursive = (selectedValue instanceof StackFrameDescriptorImpl) &&
|
||||
isOccurrenceOfSelectedFrame((StackFrameDescriptorImpl)selectedValue, descriptor);
|
||||
|
||||
final ValueMarkup markup = descriptor.getValueMarkup();
|
||||
if (markup != null) {
|
||||
append("["+ markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor()));
|
||||
}
|
||||
|
||||
boolean needSeparator = false;
|
||||
if (index > 0) {
|
||||
final int currentFrameIndex = descriptor.getUiIndex();
|
||||
final Object elementAt = list.getModel().getElementAt(index - 1);
|
||||
if (elementAt instanceof StackFrameDescriptorImpl) {
|
||||
StackFrameDescriptorImpl previousDescriptor = (StackFrameDescriptorImpl)elementAt;
|
||||
final int previousFrameIndex = previousDescriptor.getUiIndex();
|
||||
needSeparator = (currentFrameIndex - previousFrameIndex != 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
setBackground(UIUtil.getListSelectionBackground());
|
||||
}
|
||||
else {
|
||||
Color bg = descriptor.getBackgroundColor();
|
||||
if (bg == null) bg = UIUtil.getListBackground();
|
||||
if (shouldHighlightAsRecursive) bg = myColorScheme.getColor(DebuggerColors.RECURSIVE_CALL_ATTRIBUTES);
|
||||
setBackground(bg);
|
||||
}
|
||||
|
||||
if (needSeparator) {
|
||||
final MatteBorder border = BorderFactory.createMatteBorder(1, 0, 0, 0, JBColor.GRAY);
|
||||
setBorder(border);
|
||||
}
|
||||
else {
|
||||
setBorder(null);
|
||||
}
|
||||
|
||||
final String label = descriptor.getLabel();
|
||||
final int openingBrace = label.indexOf("{");
|
||||
final int closingBrace = (openingBrace < 0) ? -1 : label.indexOf("}");
|
||||
final SimpleTextAttributes attributes = getAttributes(descriptor);
|
||||
if (openingBrace < 0 || closingBrace < 0) {
|
||||
append(label, attributes);
|
||||
}
|
||||
else {
|
||||
append(label.substring(0, openingBrace - 1), attributes);
|
||||
append(" (" + label.substring(openingBrace + 1, closingBrace) + ")", SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
|
||||
|
||||
append(label.substring(closingBrace + 1, label.length()), attributes);
|
||||
if (shouldHighlightAsRecursive && descriptor.isRecursiveCall()) {
|
||||
append(" [" + descriptor.getOccurrenceIndex() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOccurrenceOfSelectedFrame(final StackFrameDescriptorImpl selectedDescriptor, StackFrameDescriptorImpl descriptor) {
|
||||
final Method currentMethod = descriptor.getMethod();
|
||||
if (currentMethod != null) {
|
||||
if (selectedDescriptor != null) {
|
||||
final Method selectedMethod = selectedDescriptor.getMethod();
|
||||
if (selectedMethod != null) {
|
||||
if (Comparing.equal(selectedMethod, currentMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static SimpleTextAttributes getAttributes(final StackFrameDescriptorImpl descriptor) {
|
||||
if (descriptor.isSynthetic() || descriptor.isInLibraryContent()) {
|
||||
return SimpleTextAttributes.GRAYED_ATTRIBUTES;
|
||||
}
|
||||
return SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class WatchPanel
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.actions.DebuggerAction;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTree;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
|
||||
import com.intellij.openapi.actionSystem.ActionPopupMenu;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public abstract class WatchPanel extends DebuggerTreePanel {
|
||||
@NonNls private static final String HELP_ID = "debugging.debugWatches";
|
||||
|
||||
public WatchPanel(Project project, DebuggerStateManager stateManager) {
|
||||
super(project, stateManager);
|
||||
add(createTreePanel(getWatchTree()), BorderLayout.CENTER);
|
||||
registerDisposable(DebuggerAction.installEditAction(getWatchTree(), DebuggerActions.EDIT_NODE_SOURCE));
|
||||
overrideShortcut(getWatchTree(), DebuggerActions.COPY_VALUE, CommonShortcuts.getCopy());
|
||||
}
|
||||
|
||||
protected JComponent createTreePanel(final WatchDebuggerTree tree) {
|
||||
return ScrollPaneFactory.createScrollPane(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DebuggerTree createTreeView() {
|
||||
return new WatchDebuggerTree(getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event == DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
return;
|
||||
}
|
||||
if(event == DebuggerSession.EVENT_ATTACHED) {
|
||||
DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getWatchTree().getModel().getRoot();
|
||||
if(root != null) {
|
||||
for(Enumeration e = root.rawChildren(); e.hasMoreElements();) {
|
||||
DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl) e.nextElement();
|
||||
((WatchItemDescriptor) child.getDescriptor()).setNew();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rebuildIfVisible(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionPopupMenu createPopupMenu() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String dataId) {
|
||||
if (PlatformDataKeys.HELP_ID.is(dataId)) {
|
||||
return HELP_ID;
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
public WatchDebuggerTree getWatchTree() {
|
||||
return (WatchDebuggerTree) getTree();
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.UnnamedConfigurable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class CompoundNodeConfigurable implements UnnamedConfigurable {
|
||||
private final CompoundNodeRenderer myRenderer;
|
||||
|
||||
private final UnnamedConfigurable myLabelConfigurable;
|
||||
private final UnnamedConfigurable myChildrenConfigurable;
|
||||
|
||||
private final static UnnamedConfigurable NULL_CONFIGURABLE = new UnnamedConfigurable() {
|
||||
public JComponent createComponent() {
|
||||
return new JPanel();
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void apply() {}
|
||||
public void reset() {}
|
||||
public void disposeUIResources() {}
|
||||
};
|
||||
|
||||
public CompoundNodeConfigurable(CompoundNodeRenderer renderer,
|
||||
UnnamedConfigurable labelConfigurable,
|
||||
UnnamedConfigurable childrenConfigurable) {
|
||||
myRenderer = renderer;
|
||||
myLabelConfigurable = labelConfigurable != null ? labelConfigurable : NULL_CONFIGURABLE;
|
||||
myChildrenConfigurable = childrenConfigurable != null ? childrenConfigurable : NULL_CONFIGURABLE;
|
||||
}
|
||||
|
||||
public CompoundNodeRenderer getRenderer() {
|
||||
return myRenderer;
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.weightx = 1.0;
|
||||
c.insets = new Insets(0, 0, 5, 0);
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
|
||||
panel.add(myLabelConfigurable.createComponent(), c);
|
||||
|
||||
c.ipady = 1;
|
||||
panel.add(new JSeparator(JSeparator.HORIZONTAL), c);
|
||||
|
||||
c.ipady = 0;
|
||||
c.weighty = 1.0;
|
||||
panel.add(myChildrenConfigurable.createComponent(), c);
|
||||
return panel;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return myLabelConfigurable.isModified() || myChildrenConfigurable.isModified();
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
myLabelConfigurable.apply();
|
||||
myChildrenConfigurable.apply();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myLabelConfigurable.reset();
|
||||
myChildrenConfigurable.reset();
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
myLabelConfigurable.disposeUIResources();
|
||||
myChildrenConfigurable.disposeUIResources();
|
||||
}
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.tree.render.configurables;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.CompletionEditor;
|
||||
import com.intellij.debugger.ui.tree.render.LabelRenderer;
|
||||
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 com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ClassLabelExpressionConfigurable implements UnnamedConfigurable{
|
||||
private final LabelRenderer myRenderer;
|
||||
private LabeledComponent<CompletionEditor> myCompletionEditor;
|
||||
private final JPanel myPanel;
|
||||
|
||||
public ClassLabelExpressionConfigurable(@NotNull Project project, LabelRenderer renderer) {
|
||||
myRenderer = renderer;
|
||||
|
||||
myCompletionEditor = new LabeledComponent<CompletionEditor>();
|
||||
final PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project));
|
||||
myCompletionEditor.setComponent(((DebuggerUtilsEx)DebuggerUtils.getInstance()).createEditor(project, psiClass, "ClassLabelExpression"));
|
||||
myCompletionEditor.setText(DebuggerBundle.message("label.class.label.expression.configurable.node.label"));
|
||||
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.add(myCompletionEditor, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return !myRenderer.getLabelExpression().equals(myCompletionEditor.getComponent().getText());
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
myRenderer.setLabelExpression(myCompletionEditor.getComponent().getText());
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myCompletionEditor.getComponent().setText(myRenderer.getLabelExpression());
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
if (myCompletionEditor != null) {
|
||||
myCompletionEditor.getComponent().dispose();
|
||||
myCompletionEditor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -219,11 +219,6 @@
|
||||
<daemon.highlightInfoFilter implementation="com.intellij.debugger.engine.evaluation.DebuggerHighlightFilter"/>
|
||||
<daemon.highlightInfoFilter implementation="com.intellij.codeInsight.daemon.impl.HighlightInfoFilterImpl"/>
|
||||
|
||||
|
||||
<projectService serviceInterface="com.intellij.debugger.ui.DebuggerRecents"
|
||||
serviceImplementation="com.intellij.debugger.ui.DebuggerRecents"/>
|
||||
|
||||
|
||||
<!-- Project Configurables -->
|
||||
<projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.ModuleStructureConfigurable"/>
|
||||
<projectService serviceImplementation="com.intellij.openapi.roots.ui.configuration.projectRoot.FacetStructureConfigurable"/>
|
||||
|
||||
Reference in New Issue
Block a user