blob: 3358962c922d1d3a492d7db13aa95267a27db62a [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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.android.ddmuilib;
import com.android.ddmlib.Client;
import com.android.ddmlib.IStackTraceInfo;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
/**
* Stack Trace Panel.
* <p/>This is not a panel in the regular sense. Instead this is just an object around the creation
* and management of a Stack Trace display.
* <p/>UI creation is done through
* {@link #createPanel(Composite, String, String, String, String, String, IPreferenceStore)}.
*
*/
public final class StackTracePanel {
private static ISourceRevealer sSourceRevealer;
private Table mStackTraceTable;
private TableViewer mStackTraceViewer;
private Client mCurrentClient;
/**
* Content Provider to display the stack trace of a thread.
* Expected input is a {@link IStackTraceInfo} object.
*/
private static class StackTraceContentProvider implements IStructuredContentProvider {
public Object[] getElements(Object inputElement) {
if (inputElement instanceof IStackTraceInfo) {
// getElement cannot return null, so we return an empty array
// if there's no stack trace
StackTraceElement trace[] = ((IStackTraceInfo)inputElement).getStackTrace();
if (trace != null) {
return trace;
}
}
return new Object[0];
}
public void dispose() {
// pass
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
// pass
}
}
/**
* A Label Provider to use with {@link StackTraceContentProvider}. It expects the elements to be
* of type {@link StackTraceElement}.
*/
private static class StackTraceLabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
public String getColumnText(Object element, int columnIndex) {
if (element instanceof StackTraceElement) {
StackTraceElement traceElement = (StackTraceElement)element;
switch (columnIndex) {
case 0:
return traceElement.getClassName();
case 1:
return traceElement.getMethodName();
case 2:
return traceElement.getFileName();
case 3:
return Integer.toString(traceElement.getLineNumber());
case 4:
return Boolean.toString(traceElement.isNativeMethod());
}
}
return null;
}
public void addListener(ILabelProviderListener listener) {
// pass
}
public void dispose() {
// pass
}
public boolean isLabelProperty(Object element, String property) {
// pass
return false;
}
public void removeListener(ILabelProviderListener listener) {
// pass
}
}
/**
* Classes which implement this interface provide a method that is able to reveal a method
* in a source editor
*/
public interface ISourceRevealer {
/**
* Sent to reveal a particular line in a source editor
* @param applicationName the name of the application running the source.
* @param className the fully qualified class name
* @param line the line to reveal
*/
public void reveal(String applicationName, String className, int line);
}
/**
* Sets the {@link ISourceRevealer} object able to reveal source code in a source editor.
* @param revealer
*/
public static void setSourceRevealer(ISourceRevealer revealer) {
sSourceRevealer = revealer;
}
/**
* Creates the controls for the StrackTrace display.
* <p/>This method will set the parent {@link Composite} to use a {@link GridLayout} with
* 2 columns.
* @param parent the parent composite.
* @param prefs_stack_col_class
* @param prefs_stack_col_method
* @param prefs_stack_col_file
* @param prefs_stack_col_line
* @param prefs_stack_col_native
* @param store
*/
public Table createPanel(Composite parent, String prefs_stack_col_class,
String prefs_stack_col_method, String prefs_stack_col_file, String prefs_stack_col_line,
String prefs_stack_col_native, IPreferenceStore store) {
mStackTraceTable = new Table(parent, SWT.MULTI | SWT.FULL_SELECTION);
mStackTraceTable.setHeaderVisible(true);
mStackTraceTable.setLinesVisible(true);
TableHelper.createTableColumn(
mStackTraceTable,
"Class",
SWT.LEFT,
"SomeLongClassName", //$NON-NLS-1$
prefs_stack_col_class, store);
TableHelper.createTableColumn(
mStackTraceTable,
"Method",
SWT.LEFT,
"someLongMethod", //$NON-NLS-1$
prefs_stack_col_method, store);
TableHelper.createTableColumn(
mStackTraceTable,
"File",
SWT.LEFT,
"android/somepackage/someotherpackage/somefile.class", //$NON-NLS-1$
prefs_stack_col_file, store);
TableHelper.createTableColumn(
mStackTraceTable,
"Line",
SWT.RIGHT,
"99999", //$NON-NLS-1$
prefs_stack_col_line, store);
TableHelper.createTableColumn(
mStackTraceTable,
"Native",
SWT.LEFT,
"Native", //$NON-NLS-1$
prefs_stack_col_native, store);
mStackTraceViewer = new TableViewer(mStackTraceTable);
mStackTraceViewer.setContentProvider(new StackTraceContentProvider());
mStackTraceViewer.setLabelProvider(new StackTraceLabelProvider());
mStackTraceViewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
if (sSourceRevealer != null && mCurrentClient != null) {
// get the selected stack trace element
ISelection selection = mStackTraceViewer.getSelection();
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection)selection;
Object object = structuredSelection.getFirstElement();
if (object instanceof StackTraceElement) {
StackTraceElement traceElement = (StackTraceElement)object;
if (traceElement.isNativeMethod() == false) {
sSourceRevealer.reveal(
mCurrentClient.getClientData().getClientDescription(),
traceElement.getClassName(),
traceElement.getLineNumber());
}
}
}
}
}
});
return mStackTraceTable;
}
/**
* Sets the input for the {@link TableViewer}.
* @param input the {@link IStackTraceInfo} that will provide the viewer with the list of
* {@link StackTraceElement}
*/
public void setViewerInput(IStackTraceInfo input) {
mStackTraceViewer.setInput(input);
mStackTraceViewer.refresh();
}
/**
* Sets the current client running the stack trace.
* @param currentClient the {@link Client}.
*/
public void setCurrentClient(Client currentClient) {
mCurrentClient = currentClient;
}
}