/**
* Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved.
* Licensed under the terms of the Eclipse Public License (EPL).
* Please see the license.txt included with this distribution for details.
* Any modifications to this file must keep this entire header intact.
*/
package org.python.pydev.debug.ui.hover;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.python.pydev.core.IPythonPartitions;
import org.python.pydev.core.docutils.PySelection;
import org.python.pydev.core.log.Log;
import org.python.pydev.debug.ui.actions.EvalExpressionAction;
import org.python.pydev.editor.hover.AbstractPyEditorTextHover;
import org.python.pydev.editor.hover.PyHoverPreferencesPage;
/**
* Gathers hover info during a debug session.
*
* @author Fabio
*/
public class PyDebugHover extends AbstractPyEditorTextHover {
public static String ID = "org.python.pydev.debug.ui.hover.PyDebugHover";
/**
* Gets the value from the debugger for the currently hovered string.
*/
@Override
public String getHoverInfo(final ITextViewer textViewer, IRegion hoverRegion) {
if (!PyHoverPreferencesPage.getShowValuesWhileDebuggingOnHover()) {
return null;
}
IAdaptable object = DebugUITools.getDebugContext();
IDebugElement context = null;
if (object instanceof IDebugElement) {
context = (IDebugElement) object;
} else if (object instanceof ILaunch) {
context = ((ILaunch) object).getDebugTarget();
}
if (context != null) {
IDebugTarget debugTarget = context.getDebugTarget();
if (debugTarget == null || debugTarget.isTerminated()) {
return null;
}
String act = null;
final ITextSelection[] textSelection = new ITextSelection[1];
if (Thread.currentThread() == textViewer.getTextWidget().getDisplay().getThread()) {
textSelection[0] = (ITextSelection) textViewer.getSelectionProvider().getSelection();
} else {
textViewer.getTextWidget().getDisplay().syncExec(new Runnable() {
@Override
public void run() {
textSelection[0] = (ITextSelection) textViewer.getSelectionProvider().getSelection();
}
});
}
PySelection ps = new PySelection(textViewer.getDocument(),
hoverRegion.getOffset() + hoverRegion.getLength());
int mouseOffset = ps.getAbsoluteCursorOffset();
int offset = textSelection[0].getOffset();
int len = textSelection[0].getLength();
boolean reportSyntaxErrors = false;
if (len > 0 && mouseOffset >= offset && offset + len >= mouseOffset) {
try {
act = ps.getDoc().get(offset, len);
reportSyntaxErrors = true; //the user has text selected
} catch (BadLocationException e) {
//that's Ok... we were not able to get the actual selection here
Log.log(e);
}
}
if (act == null || act.trim().length() == 0) {
String[] activationTokenAndQual = ps.getActivationTokenAndQual(true);
act = activationTokenAndQual[0] + activationTokenAndQual[1];
}
//OK, we're in a debug context...
IWatchExpression watchExpression = EvalExpressionAction.createWatchExpression(act);
watchExpression.evaluate();
EvalExpressionAction.waitForExpressionEvaluation(watchExpression);
IValue value = watchExpression.getValue();
if (value != null) {
try {
String valueString = value.getValueString();
if (valueString != null) {
if (!reportSyntaxErrors) {
if (valueString.startsWith("SyntaxError") && valueString.indexOf("<string>") != -1) {
//Don't report syntax errors in the hover
return null;
}
}
return valueString + "\n";
}
} catch (DebugException e) {
Log.log(e);
}
}
}
return null;
}
@Override
public boolean isContentTypeSupported(String contentType) {
boolean pythonCommentOrMultiline = IPythonPartitions.NON_DEFAULT_TYPES_AS_SET.contains(contentType);
return !pythonCommentOrMultiline;
}
}