sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.call/src/com/nokia/carbide/cpp/pi/call/CallVisualiser.java
/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
/**
*
*/
package com.nokia.carbide.cpp.pi.call;
//import java.awt.Color;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseEvent;
import java.text.DecimalFormat;
import java.util.Vector;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IContributionManager;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.SubMenuManager;
import org.eclipse.jface.dialogs.IPageChangedListener;
import org.eclipse.jface.dialogs.PageChangedEvent;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.ide.IIDEActionConstants;
import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveTable;
import com.nokia.carbide.cpp.internal.pi.save.SaveTableWizard;
import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;
import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
import com.nokia.carbide.cpp.pi.util.SourceLookup;
public class CallVisualiser extends GenericTable
{
private static final long serialVersionUID = 1L;
// table column IDs in hopes it's quicker than comparing characters
protected static final int COLUMN_ID_IS_CALLED = 100;
protected static final int COLUMN_ID_IS_CALLER = 101;
protected static final int COLUMN_ID_RECURSIVE_CALL = 102;
protected static final int COLUMN_ID_CALLER_PERCENT = 103;
protected static final int COLUMN_ID_CALLEE_PERCENT = 104;
protected static final int COLUMN_ID_IS_CALLED_COUNT = 105;
protected static final int COLUMN_ID_IS_CALLER_COUNT = 106;
// table column headings
protected static final String COLUMN_HEAD_IS_CALLED = Messages.getString("CallVisualiser.isCalled"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_IS_CALLER = Messages.getString("CallVisualiser.isCaller"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_RECURSIVE_CALL = Messages.getString("CallVisualiser.recursiveCaller"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_CALLER_PERCENT = Messages.getString("CallVisualiser.percentOfCalls"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_CALLEE_PERCENT = Messages.getString("CallVisualiser.percentOfCalls"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_IS_CALLED_COUNT = Messages.getString("CallVisualiser.calledSamples"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_IS_CALLER_COUNT = Messages.getString("CallVisualiser.callerSamples"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_IS_CALLED_COUNT2 = Messages.getString("CallVisualiser.calls"); //$NON-NLS-1$
protected static final String COLUMN_HEAD_IS_CALLER_COUNT2 = Messages.getString("CallVisualiser.calls"); //$NON-NLS-1$
// table column widths
protected static final int COLUMN_WIDTH_IS_CALLED = 70;
protected static final int COLUMN_WIDTH_IS_CALLER = 70;
protected static final int COLUMN_WIDTH_RECURSIVE_CALL = 105;
protected static final int COLUMN_WIDTH_CALLER_PERCENT = 98;
protected static final int COLUMN_WIDTH_CALLEE_PERCENT = 98;
protected static final int COLUMN_WIDTH_IS_CALLED_COUNT = 113;
protected static final int COLUMN_WIDTH_IS_CALLER_COUNT = 85;
protected static final int COLUMN_WIDTH_IS_CALLED_COUNT2 = 65;
protected static final int COLUMN_WIDTH_IS_CALLER_COUNT2 = 65;
// SashForm to hold the tables and their titles
private SashForm sashForm;
// Table viewers and their tables
private TableViewer callerTableViewer;
private Table callerTable;
private TableViewer currentFunctionTableViewer;
private Table currentFunctionTable;
private TableColumn currentFunctionDefaultColumn;
private TableViewer calleeTableViewer;
private Table calleeTable;
// context menus
private Menu callerMenu;
private Menu currentFunctionMenu;
private Menu calleeMenu;
private Table currentMenuTable;
private SashForm parent;
// this display's editor and page
private PIPageEditor pageEditor;
private int pageIndex;
// trace associated with this display
private GfcTrace myTrace;
/** the editor page this is sitting on */
private Composite curPage;
protected boolean isPageActive;
protected boolean needsRefresh;
//start and end of the timeframe at the last selection event
private int curStart;
private int curEnd;
// lists of functions, function callers, and function callees
private GfcFunctionItem[] functionArray;
private CallerCalleeItem[] callerList;
private CallerCalleeItem[] calleeList;
// menu items
protected Action copyAction;
protected Action copyTableAction;
protected Action functionCopyFunctionAction;
protected Action saveTableAction;
protected Action functionSaveFunctionAction;
protected static int SAMPLES_AT_ONE_TIME = 1000;
private Job setTimeframeJob = null;
// class to pass sample data to the save wizard
public class SaveSampleString implements ISaveSamples {
int startIndex = 0;
public SaveSampleString() {
}
public String getData() {
return getData(SAMPLES_AT_ONE_TIME);
}
public String getData(int size) {
String returnString = getSampleString(this.startIndex, this.startIndex + size);
if (returnString == null)
this.startIndex = 0;
else
this.startIndex += size;
return returnString;
}
public int getIndex() {
return this.startIndex;
}
public void clear() {
this.startIndex = 0;
}
}
/*
* return the call samples selected in the interval
*/
protected String getSampleString(int startIndex, int endIndex)
{
int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0 + 0.0005);
int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0 + 0.0005);
// check if we have returned everything
if (startIndex > (endTime - startTime))
return null;
GfcTrace trace = this.myTrace;
Vector samples = trace.samples;
String returnString = ""; //$NON-NLS-1$
if (startIndex == 0)
returnString = Messages.getString("CallVisualiser.callHeading"); //$NON-NLS-1$
for (int i = startTime + startIndex; i < endTime && i < startTime + endIndex; i++) {
GfcSample sample = (GfcSample) samples.get(i);
returnString += sample.sampleSynchTime + ",0x" //$NON-NLS-1$
+ Long.toHexString(sample.linkRegister)
+ ",\"" //$NON-NLS-1$
+ (sample.getCallerFunctionItt() != null
? sample.getCallerFunctionItt().getFunctionName()
: sample.getCallerFunctionSym().getFunctionName())
+ "\"," //$NON-NLS-1$
+ (sample.getCallerFunctionItt() != null
? sample.getCallerFunctionItt().getFunctionBinary().getBinaryName()
: sample.getCallerFunctionSym().getFunctionBinary().getBinaryName())
+ ",0x" //$NON-NLS-1$
+ Long.toHexString(sample.programCounter)
+ ",\"" //$NON-NLS-1$
+ (sample.getCurrentFunctionItt() != null
? sample.getCurrentFunctionItt().getFunctionName()
: sample.getCurrentFunctionSym().getFunctionName())
+ "\"," //$NON-NLS-1$
+ (sample.getCurrentFunctionItt() != null
? sample.getCurrentFunctionItt().getFunctionBinary().getBinaryName()
: sample.getCurrentFunctionSym().getFunctionBinary().getBinaryName())
+ "\n"; //$NON-NLS-1$
}
return returnString;
}
protected MenuItem getSaveSamplesItem(Menu menu, boolean enabled) {
MenuItem saveSamplesItem = new MenuItem(menu, SWT.PUSH);
saveSamplesItem.setText(Messages.getString("CallVisualiser.saveAllSamplesForInterval")); //$NON-NLS-1$
saveSamplesItem.setEnabled(enabled);
if (enabled) {
saveSamplesItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
action("saveSamples"); //$NON-NLS-1$
}
});
}
return saveSamplesItem;
}
public CallVisualiser(PIPageEditor pageEditor, int pageIndex, SashForm parent, GfcTrace trace, Composite curPage)
{
this.pageEditor = pageEditor;
this.pageIndex = pageIndex;
this.parent = parent;
this.myTrace = trace;
this.curPage = curPage;
isPageActive = true;
needsRefresh = false;
// let the trace know about the CallVisualiser so that unit tests can find it
trace.setCallVisualiser(this);
// create the 3 table viewers: caller functions, selected function, callee functions
createTableViewers(parent);
createSetTimeframeJob();
createPageListeners();
}
public void createTableViewers(SashForm parent)
{
if (parent == null)
return;
/*
* Create a SashForm with three labeled tables:
*
* 1. Functions called by
* 2. Functions (one checkbox selectable at a time)
* 3. Functions called
*/
// the 3 tables will be in a sashForm
if (parent.getOrientation() != SWT.VERTICAL)
{
// put a SashForm in the SashForm
this.sashForm = new SashForm(parent, SWT.VERTICAL);
this.sashForm.SASH_WIDTH = 5; // 5 pixel wide sash
} else
this.sashForm = parent;
createCallerTableViewer(sashForm);
createCurrentFunctionTableViewer(sashForm);
createCalleeTableViewer(sashForm);
createDefaultActions(true);
}
private void createCurrentFunctionTableViewer(SashForm sashForm)
{
/*
* Functions (one checkbox selectable at a time)
*
* selected checkbox
* percent load
* function name
* function start address
* binary containing function
* sample count
*/
Label label;
Composite holder;
Table table;
TableColumn column;
// middle functionTable and title
holder = new Composite(sashForm, SWT.NONE);
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
holder.setLayout(gridLayout);
label = new Label(holder, SWT.CENTER | SWT.BORDER);
label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_YELLOW));
label.setFont(PIPageEditor.helvetica_10);
label.setText(Messages.getString("CallVisualiser.selectFunction")); //$NON-NLS-1$
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
this.currentFunctionTableViewer = new TableViewer(holder,
SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
this.currentFunctionTable = currentFunctionTableViewer.getTable();
// add the label provider and content provider
this.currentFunctionTableViewer.setLabelProvider(new SharedLabelProvider(this.currentFunctionTable));
this.currentFunctionTableViewer.setContentProvider(new ArrayContentProvider());
this.currentFunctionTableViewer.setSorter(new SharedSorter());
table = this.currentFunctionTable;
table.setRedraw(false);
// give the table a heading for use in copying and exported
table.setData(Messages.getString("CallVisualiser.selectedFunction")); //$NON-NLS-1$
// create the other table entries when a row in this table is selected
table.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent event) {
if (!(event.item instanceof TableItem))
return;
// set the other tables based on this selection
if (!(event.item.getData() instanceof GfcFunctionItem))
return;
updateCallerCalleeTables((GfcFunctionItem)event.item.getData());
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}});
// data associated with the TableViewer will note which columns contain hex values
// Keep this in the order in which columns have been created
boolean[] isHex = {false, false, false, true, false, false, false};
this.currentFunctionTable.setData("isHex", isHex); //$NON-NLS-1$
// is called percent column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_IS_CALLED);
column.setWidth(COLUMN_WIDTH_IS_CALLED);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// is caller percent column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_IS_CALLER);
column.setWidth(COLUMN_WIDTH_IS_CALLER);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// function name column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_FUNCTION);
column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// function start address column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_START_ADDR);
column.setWidth(COLUMN_WIDTH_START_ADDRESS);
column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY);
column.setWidth(COLUMN_WIDTH_IN_BINARY);
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// path to binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY_PATH);
column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// sample count column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_IS_CALLED_COUNT);
column.setWidth(COLUMN_WIDTH_IS_CALLED_COUNT);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED_COUNT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
// set the default sort column to COLUMN_ID_IS_CALLED_COUNT
currentFunctionDefaultColumn = column;
// sample count column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_IS_CALLER_COUNT);
column.setWidth(COLUMN_WIDTH_IS_CALLER_COUNT);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER_COUNT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CheckboxColumnSelectionHandler());
table.setLayoutData(new GridData(GridData.FILL_BOTH));
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setRedraw(true);
// listen for mouse clicks: to select a row, pop up a menu, etc.
table.addMouseListener(new CurrentFunctionMouseListener());
table.addFocusListener(new FocusListener() {
IAction oldCopyAction = null;
public void focusGained(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
// modify what is executed when Copy is called from the Edit menu
oldCopyAction = bars.getGlobalActionHandler(ActionFactory.COPY.getId());
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
copyAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
bars.updateActionBars();
// add to the Edit menu
IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT);
if (editMenuManager instanceof SubMenuManager)
{
IContributionManager editManager = ((SubMenuManager)editMenuManager).getParent();
ActionContributionItem item;
editMenuManager.remove("PICopyFunction"); //$NON-NLS-1$
functionCopyFunctionAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
item = new ActionContributionItem(functionCopyFunctionAction);
item.setVisible(true);
editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
copyTableAction.setEnabled(currentFunctionTable.getItemCount() > 0);
item = new ActionContributionItem(copyTableAction);
item.setVisible(true);
editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
}
// add to the File menu
IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE);
if (fileMenuManager instanceof SubMenuManager)
{
IContributionManager fileManager = ((SubMenuManager)fileMenuManager).getParent();
ActionContributionItem item;
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
saveTableAction.setEnabled(currentFunctionTable.getItemCount() > 0);
item = new ActionContributionItem(saveTableAction);
item.setVisible(true);
fileManager.insertAfter("saveAll", item); //$NON-NLS-1$
fileMenuManager.remove("PISaveFunction"); //$NON-NLS-1$
functionSaveFunctionAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
item = new ActionContributionItem(functionSaveFunctionAction);
item.setVisible(true);
fileManager.insertAfter("PISaveTable", item); //$NON-NLS-1$
}
}
public void focusLost(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction);
bars.updateActionBars();
SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_EDIT);
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
editMenuManager.remove("PICopyFunction"); //$NON-NLS-1$
SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_FILE);
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
fileMenuManager.remove("PISaveFunction"); //$NON-NLS-1$
}
});
}
private void createCallerTableViewer(SashForm sashForm)
{
/*
* Functions called by
*
* percent of calls
* total percent
* caller percent
* function name
* function start address
* binary containing function
* sample count
*/
Label label;
Composite holder;
Table table;
TableColumn column;
// top functionTable and title
holder = new Composite(sashForm, SWT.NONE);
// holder.setLayout(new FillLayout(SWT.VERTICAL));
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
holder.setLayout(gridLayout);
label = new Label(holder, SWT.CENTER | SWT.BORDER);
label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_CYAN));
label.setFont(PIPageEditor.helvetica_10);
label.setText(Messages.getString("CallVisualiser.callingSelectedFunction")); //$NON-NLS-1$
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
this.callerTableViewer = new TableViewer(holder,
SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
this.callerTable = callerTableViewer.getTable();
// add the label provider and content provider
this.callerTableViewer.setLabelProvider(new SharedLabelProvider(this.callerTable));
this.callerTableViewer.setContentProvider(new ArrayContentProvider());
this.callerTableViewer.setSorter(new SharedSorter());
table = this.callerTable;
table.setRedraw(false);
// give the table a heading for possible use in copying and exported
table.setData(Messages.getString("CallVisualiser.callerFunctions")); //$NON-NLS-1$
// data associated with the TableViewer will note which columns contain hex values
// Keep this in the order in which columns have been created
boolean[] isHex = {false, false, false, true, false, false, false};
this.callerTable.setData("isHex", isHex); //$NON-NLS-1$
// percent of calls column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_CALLER_PERCENT);
column.setWidth(COLUMN_WIDTH_CALLER_PERCENT);
column.setData(Integer.valueOf(COLUMN_ID_CALLER_PERCENT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// sample count column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_IS_CALLER_COUNT2);
column.setWidth(COLUMN_WIDTH_IS_CALLER_COUNT2);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER_COUNT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// function name column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_FUNCTION);
column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// function start address column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_START_ADDR);
column.setWidth(COLUMN_WIDTH_START_ADDRESS);
column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY);
column.setWidth(COLUMN_WIDTH_IN_BINARY);
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// path to binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY_PATH);
column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
// is caller percent column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_IS_CALLER);
column.setWidth(COLUMN_WIDTH_IS_CALLER);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLER));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledByColumnSelectionHandler());
table.setLayoutData(new GridData(GridData.FILL_BOTH));
// table.setLayout(new FillLayout());
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setRedraw(true);
// when a row is selected, allow the user to double-click or right click and make that function the selected function
table.addSelectionListener(new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent se) {
TableItem item = (TableItem)se.item;
Table table = (Table)se.widget;
CallerCalleeItem callerCalleeItem = (CallerCalleeItem)item.getData();
// deselect this line
table.deselectAll();
// choose this row's function
chooseNewFunction(callerCalleeItem);
}
});
table.addMouseListener(new CallerMouseListener());
table.addFocusListener(new FocusListener() {
IAction oldCopyAction = null;
public void focusGained(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
// modify what is executed when Copy is called from the Edit menu
oldCopyAction = bars.getGlobalActionHandler(ActionFactory.COPY.getId());
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
copyAction.setEnabled(callerTable.getSelectionCount() > 0);
bars.updateActionBars();
// add to the Edit menu
IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT);
if (editMenuManager instanceof SubMenuManager)
{
IContributionManager editManager = ((SubMenuManager)editMenuManager).getParent();
ActionContributionItem item;
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
copyTableAction.setEnabled(callerTable.getItemCount() > 0);
item = new ActionContributionItem(copyTableAction);
item.setVisible(true);
editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
}
// add to the File menu
IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE);
if (fileMenuManager instanceof SubMenuManager)
{
IContributionManager fileManager = ((SubMenuManager)fileMenuManager).getParent();
ActionContributionItem item;
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
saveTableAction.setEnabled(callerTable.getItemCount() > 0);
item = new ActionContributionItem(saveTableAction);
item.setVisible(true);
fileManager.insertAfter("saveAll", item); //$NON-NLS-1$
}
}
public void focusLost(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction);
bars.updateActionBars();
SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_EDIT);
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_FILE);
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
}
});
}
private void createCalleeTableViewer(SashForm sashForm)
{
/*
* Functions called
*
* percent of calls
* total percent
* caller percent
* function name
* function start address
* binary containing function
* sample count
*/
Label label;
Composite holder;
Table table;
TableColumn column;
// bottom functionTable and title
holder = new Composite(sashForm, SWT.NONE);
// holder.setLayout(new FillLayout(SWT.VERTICAL));
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
holder.setLayout(gridLayout);
label = new Label(holder, SWT.CENTER | SWT.BORDER);
label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_CYAN));
label.setFont(PIPageEditor.helvetica_10);
label.setText(Messages.getString("CallVisualiser.calledBySelectedFunction")); //$NON-NLS-1$
label.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
this.calleeTableViewer = new TableViewer(holder,
SWT.BORDER | SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
this.calleeTable = calleeTableViewer.getTable();
// add the label provider and content provider
this.calleeTableViewer.setLabelProvider(new SharedLabelProvider(this.calleeTable));
this.calleeTableViewer.setContentProvider(new ArrayContentProvider());
this.calleeTableViewer.setSorter(new SharedSorter());
table = this.calleeTable;
table.setRedraw(false);
// give the table a heading for possible use in copying and exported
table.setData(Messages.getString("CallVisualiser.calleeFunctions")); //$NON-NLS-1$
// data associated with the TableViewer will note which columns contain hex values
// Keep this in the order in which columns have been created
boolean[] isHex = {false, false, false, true, false, false, false};
this.calleeTable.setData("isHex", isHex); //$NON-NLS-1$
// percent of calls column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_CALLEE_PERCENT);
column.setWidth(COLUMN_WIDTH_CALLEE_PERCENT);
column.setData(Integer.valueOf(COLUMN_ID_CALLEE_PERCENT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// sample count column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_IS_CALLED_COUNT2);
column.setWidth(COLUMN_WIDTH_IS_CALLED_COUNT2);
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED_COUNT));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// function name column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_FUNCTION);
column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
column.setData(Integer.valueOf(COLUMN_ID_FUNCTION));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// function start address column
column = new TableColumn(table, SWT.CENTER);
column.setText(COLUMN_HEAD_START_ADDR);
column.setWidth(COLUMN_WIDTH_START_ADDRESS);
// column.setData(Integer.valueOf(COLUMN_ID_START_ADDR3));
column.setData(Integer.valueOf(COLUMN_ID_START_ADDR));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY);
column.setWidth(COLUMN_WIDTH_IN_BINARY);
// column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY3));
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// path to binary containing function column
column = new TableColumn(table, SWT.LEFT);
column.setText(COLUMN_HEAD_IN_BINARY_PATH);
column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
// column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH3));
column.setData(Integer.valueOf(COLUMN_ID_IN_BINARY_PATH));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
// percent of calls column
column = new TableColumn(table, SWT.RIGHT);
column.setText(COLUMN_HEAD_IS_CALLED);
column.setWidth(COLUMN_WIDTH_IS_CALLED);
// column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED3));
column.setData(Integer.valueOf(COLUMN_ID_IS_CALLED));
column.setMoveable(true);
column.setResizable(true);
column.addSelectionListener(new CalledColumnSelectionHandler());
table.setLayoutData(new GridData(GridData.FILL_BOTH));
// table.setLayout(new FillLayout());
table.setHeaderVisible(true);
table.setLinesVisible(true);
table.setRedraw(true);
// when a row is selected, allow the user to double-click or right click and make that function the selected function
table.addSelectionListener(new SelectionAdapter() {
public void widgetDefaultSelected(SelectionEvent se) {
TableItem item = (TableItem)se.item;
Table table = (Table)se.widget;
CallerCalleeItem callerCallee = (CallerCalleeItem)item.getData();
// deselect this row
table.deselectAll();
// choose this row's function
chooseNewFunction(callerCallee);
}
});
table.addMouseListener(new CalleeMouseListener());
table.addFocusListener(new FocusListener() {
IAction oldCopyAction = null;
public void focusGained(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
// modify what is executed when Copy is called from the Edit menu
oldCopyAction = bars.getGlobalActionHandler(ActionFactory.COPY.getId());
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction);
copyAction.setEnabled(calleeTable.getSelectionCount() > 0);
bars.updateActionBars();
// add to the Edit menu
IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT);
if (editMenuManager instanceof SubMenuManager)
{
IContributionManager editManager = ((SubMenuManager)editMenuManager).getParent();
ActionContributionItem item;
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
copyTableAction.setEnabled(calleeTable.getItemCount() > 0);
item = new ActionContributionItem(copyTableAction);
item.setVisible(true);
editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item);
}
// add to the File menu
IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE);
if (fileMenuManager instanceof SubMenuManager)
{
IContributionManager fileManager = ((SubMenuManager)fileMenuManager).getParent();
ActionContributionItem item;
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
saveTableAction.setEnabled(calleeTable.getItemCount() > 0);
item = new ActionContributionItem(saveTableAction);
item.setVisible(true);
fileManager.insertAfter("saveAll", item); //$NON-NLS-1$
}
}
public void focusLost(org.eclipse.swt.events.FocusEvent arg0) {
IActionBars bars = PIPageEditor.getActionBars();
bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction);
bars.updateActionBars();
SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_EDIT);
editMenuManager.remove("PICopyTable"); //$NON-NLS-1$
SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager().find(IIDEActionConstants.M_FILE);
fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$
}
});
}
private void chooseNewFunction(CallerCalleeItem callerCalleeItem)
{
// find the correct line in the function table and select it
int count = currentFunctionTable.getItemCount();
for (int i = 0; i < count; i++) {
GfcFunctionItem functionItem = (GfcFunctionItem)(currentFunctionTable.getItem(i).getData());
if ( functionItem.name.equals(callerCalleeItem.item.name)
&& functionItem.dllName.equals(callerCalleeItem.item.dllName)) {
currentFunctionTable.select(i);
currentFunctionTable.showSelection();
updateCallerCalleeTables(functionItem);
return;
}
}
}
public void updateCallerCalleeTables(GfcFunctionItem item)
{
Table table;
TableColumn sortByColumn;
setCallerListToFunctionsThatCallThisFunction(item);
setCalleeListToFunctionsThisFunctionCalls(item);
callerTableViewer.setInput(callerList);
if ((callerList != null) && (callerList.length > 0)) {
SharedSorter sorter = ((SharedSorter) callerTableViewer.getSorter());
int columnID = sorter.getColumnID();
if (columnID == -1) {
columnID = COLUMN_ID_CALLER_PERCENT;
} else {
sorter.setSortAscending(!sorter.getSortAscending());
}
sorter.doSort(columnID);
sortByColumn = null;
table = callerTableViewer.getTable();
for (int i = 0; i < table.getColumnCount(); i++) {
if (table.getColumn(i).getData() instanceof Integer) {
if (((Integer)table.getColumn(i).getData()) == columnID) {
sortByColumn = table.getColumn(i);
break;
}
}
}
if (sortByColumn != null) {
table.setSortColumn(sortByColumn);
table.setSortDirection(sorter.getSortAscending() ? SWT.UP : SWT.DOWN);
}
callerTableViewer.refresh();
} else {
callerTableViewer.getTable().setSortColumn(null);
}
calleeTableViewer.setInput(calleeList);
if ((calleeList != null) && (calleeList.length > 0)) {
SharedSorter sorter = ((SharedSorter) calleeTableViewer.getSorter());
int columnID = sorter.getColumnID();
if (columnID == -1) {
columnID = COLUMN_ID_CALLEE_PERCENT;
} else {
sorter.setSortAscending(!sorter.getSortAscending());
}
sorter.doSort(columnID);
sortByColumn = null;
table = calleeTableViewer.getTable();
for (int i = 0; i < table.getColumnCount(); i++) {
if (table.getColumn(i).getData() instanceof Integer) {
if (((Integer)table.getColumn(i).getData()) == columnID) {
sortByColumn = table.getColumn(i);
break;
}
}
}
if (sortByColumn != null) {
table.setSortColumn(sortByColumn);
table.setSortDirection(sorter.getSortAscending() ? SWT.UP : SWT.DOWN);
}
calleeTableViewer.refresh();
} else {
calleeTableViewer.getTable().setSortColumn(null);
}
}
private class CallerMouseListener implements MouseListener
{
public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent me) {}
public void mouseDown(org.eclipse.swt.events.MouseEvent me) {}
public void mouseUp(org.eclipse.swt.events.MouseEvent me) {
copyAction.setEnabled(callerTable.getSelectionCount() > 0);
copyTableAction.setEnabled(callerTable.getItemCount() > 0);
// only look for button 3 (right click)
if (me.button != MouseEvent.BUTTON3)
return;
// make the caller table the menu table
currentMenuTable = callerTable;
if (callerMenu != null) {
callerMenu.dispose();
}
callerMenu = new Menu(callerTable.getShell(), SWT.POP_UP);
MenuItem showCallInfoItem = new MenuItem(callerMenu, SWT.PUSH);
showCallInfoItem.setText(Messages.getString("CallVisualiser.showCallInfo")); //$NON-NLS-1$
showCallInfoItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent se) {
// based on the table's selected item, update the tables
TableItem[] selections = callerTable.getSelection();
callerTable.deselectAll();
if (selections.length != 0)
chooseNewFunction((CallerCalleeItem)selections[0].getData());
}
});
new MenuItem(callerMenu, SWT.SEPARATOR);
MenuItem sourceLookupItem = new MenuItem(callerMenu, SWT.PUSH);
sourceLookupItem.setText(Messages.getString("CallVisualiser.sourcelookup")); //$NON-NLS-1$
sourceLookupItem.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
doSourceLookup(callerTable);
}
});
if (callerTable.getSelectionCount() == 0) {
showCallInfoItem.setEnabled(false);
sourceLookupItem.setEnabled(false);
}
// add copy, copy all, and save all
new MenuItem(callerMenu, SWT.SEPARATOR);
getCopyItem(callerMenu, callerTable.getSelectionCount() > 0);
getCopyTableItem(callerMenu, callerTable.getItemCount() > 0);
copyAction.setEnabled(callerTable.getSelectionCount() > 0);
copyTableAction.setEnabled(callerTable.getItemCount() > 0);
new MenuItem(callerMenu, SWT.SEPARATOR);
getSaveTableItem(callerMenu, callerTable.getItemCount() > 0);
saveTableAction.setEnabled(callerTable.getItemCount() > 0);
// save samples
int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0f);
int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0f);
if ((startTime == -1) || (endTime == -1) || (startTime == endTime))
getSaveSamplesItem(callerMenu, false); //$NON-NLS-1$
else
getSaveSamplesItem(callerMenu, true); //$NON-NLS-1$
callerMenu.setLocation(callerTable.getParent().toDisplay(me.x, me.y));
callerMenu.setVisible(true);
callerTable.setMenu(callerMenu);
}
}
private class CurrentFunctionMouseListener implements MouseListener
{
public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent me) {}
public void mouseDown(org.eclipse.swt.events.MouseEvent me) {}
public void mouseUp(org.eclipse.swt.events.MouseEvent me) {
copyAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
copyTableAction.setEnabled(currentFunctionTable.getItemCount() > 0);
functionCopyFunctionAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
// only look for button 3 (right click)
if (me.button != MouseEvent.BUTTON3)
return;
// make the current function table the menu table
currentMenuTable = currentFunctionTable;
if (currentFunctionMenu != null) {
currentFunctionMenu.dispose();
}
currentFunctionMenu = new Menu(currentFunctionTable.getShell(), SWT.POP_UP);
// new MenuItem(callerMenu, SWT.SEPARATOR);
MenuItem sourceLookupItem = new MenuItem(currentFunctionMenu, SWT.PUSH);
sourceLookupItem.setText(Messages.getString("CallVisualiser.sourcelookup")); //$NON-NLS-1$
sourceLookupItem.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
doSourceLookup(currentFunctionTable);
}
});
if (currentFunctionTable.getSelectionCount() == 0) {
sourceLookupItem.setEnabled(false);
}
// add copy, copy all, copy caller/callee info, save all, save caller/callee info
new MenuItem(currentFunctionMenu, SWT.SEPARATOR);
getCopyItem(currentFunctionMenu, currentFunctionTable.getSelectionCount() > 0);
getCopyTableItem(currentFunctionMenu, currentFunctionTable.getItemCount() > 0);
getCopyFunctionItem(currentFunctionMenu, currentFunctionTable.getSelectionCount() > 0);
copyAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
copyTableAction.setEnabled(currentFunctionTable.getItemCount() > 0);
functionCopyFunctionAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
new MenuItem(currentFunctionMenu, SWT.SEPARATOR);
getSaveTableItem(currentFunctionMenu, currentFunctionTable.getItemCount() > 0);
getSaveFunctionItem(currentFunctionMenu, currentFunctionTable.getSelectionCount() > 0);
saveTableAction.setEnabled(currentFunctionTable.getItemCount() > 0);
functionSaveFunctionAction.setEnabled(currentFunctionTable.getSelectionCount() > 0);
// save samples
int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0f);
int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0f);
if ((startTime == -1) || (endTime == -1) || (startTime == endTime))
getSaveSamplesItem(currentFunctionMenu, false); //$NON-NLS-1$
else
getSaveSamplesItem(currentFunctionMenu, true); //$NON-NLS-1$
currentFunctionMenu.setLocation(currentFunctionTable.getParent().toDisplay(me.x, me.y));
currentFunctionMenu.setVisible(true);
currentFunctionTable.setMenu(currentFunctionMenu);
}
}
private class CalleeMouseListener implements MouseListener
{
public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent me) {}
public void mouseDown(org.eclipse.swt.events.MouseEvent me) {}
public void mouseUp(org.eclipse.swt.events.MouseEvent me) {
copyAction.setEnabled(calleeTable.getSelectionCount() > 0);
copyTableAction.setEnabled(calleeTable.getItemCount() > 0);
// only look for button 3 (right click)
if (me.button != MouseEvent.BUTTON3)
return;
// make the callee table the menu table
currentMenuTable = calleeTable;
if (calleeMenu != null) {
calleeMenu.dispose();
}
calleeMenu = new Menu(calleeTable.getShell(), SWT.POP_UP);
MenuItem showCallInfoItem = new MenuItem(calleeMenu, SWT.PUSH);
showCallInfoItem.setText(Messages.getString("CallVisualiser.showCallInfo")); //$NON-NLS-1$
showCallInfoItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent se) {
// based on the table's selected item, update the tables
TableItem[] selections = calleeTable.getSelection();
calleeTable.deselectAll();
if (selections.length != 0)
chooseNewFunction((CallerCalleeItem)selections[0].getData());
}
});
new MenuItem(calleeMenu, SWT.SEPARATOR);
MenuItem sourceLookupItem = new MenuItem(calleeMenu, SWT.PUSH);
sourceLookupItem.setText(Messages.getString("CallVisualiser.sourcelookup")); //$NON-NLS-1$
sourceLookupItem.addSelectionListener(new SelectionListener() {
public void widgetDefaultSelected(SelectionEvent arg0) {
}
public void widgetSelected(SelectionEvent arg0) {
doSourceLookup(calleeTable);
}
});
if (calleeTable.getSelectionCount() == 0) {
showCallInfoItem.setEnabled(false);
sourceLookupItem.setEnabled(false);
}
// add copy, copy all, and save all
new MenuItem(calleeMenu, SWT.SEPARATOR);
getCopyItem(calleeMenu, calleeTable.getSelectionCount() > 0);
getCopyTableItem(calleeMenu, calleeTable.getItemCount() > 0);
copyAction.setEnabled(calleeTable.getSelectionCount() > 0);
copyTableAction.setEnabled(calleeTable.getItemCount() > 0);
new MenuItem(calleeMenu, SWT.SEPARATOR);
getSaveTableItem(calleeMenu, calleeTable.getItemCount() > 0);
saveTableAction.setEnabled(calleeTable.getItemCount() > 0);
// save samples
int startTime = (int) (PIPageEditor.currentPageEditor().getStartTime() * 1000.0f);
int endTime = (int) (PIPageEditor.currentPageEditor().getEndTime() * 1000.0f);
if ((startTime == -1) || (endTime == -1) || (startTime == endTime))
getSaveSamplesItem(calleeMenu, false); //$NON-NLS-1$
else
getSaveSamplesItem(calleeMenu, true); //$NON-NLS-1$
calleeMenu.setLocation(calleeTable.getParent().toDisplay(me.x, me.y));
calleeMenu.setVisible(true);
calleeTable.setMenu(calleeMenu);
}
}
protected void createDefaultActions(boolean copyFunction)
{
copyAction = new Action(Messages.getString("CallVisualiser.0")) { //$NON-NLS-1$
public void run() {
action("copy"); //$NON-NLS-1$
}
};
copyAction.setEnabled(false);
copyTableAction = new Action(Messages.getString("CallVisualiser.1")) { //$NON-NLS-1$
public void run() {
action("copyTable"); //$NON-NLS-1$
}
};
copyTableAction.setEnabled(true);
copyTableAction.setId("PICopyTable"); //$NON-NLS-1$
copyTableAction.setText(Messages.getString("CallVisualiser.CopyTable")); //$NON-NLS-1$
saveTableAction = new Action(Messages.getString("CallVisualiser.2")) { //$NON-NLS-1$
public void run() {
action("saveTable"); //$NON-NLS-1$
}
};
saveTableAction.setEnabled(true);
saveTableAction.setId("PISaveTable"); //$NON-NLS-1$
saveTableAction.setText(Messages.getString("CallVisualiser.SaveTable")); //$NON-NLS-1$
functionCopyFunctionAction = new Action(Messages.getString("CallVisualiser.3")) { //$NON-NLS-1$
public void run() {
action("copyFunction"); //$NON-NLS-1$
}
};
functionCopyFunctionAction.setEnabled(true);
functionCopyFunctionAction.setId("PICopyFunction"); //$NON-NLS-1$
functionCopyFunctionAction.setText(Messages.getString("CallVisualiser.CopyDataForFunction")); //$NON-NLS-1$
functionSaveFunctionAction = new Action(Messages.getString("CallVisualiser.4")) { //$NON-NLS-1$
public void run() {
action("saveFunction"); //$NON-NLS-1$
}
};
functionSaveFunctionAction.setEnabled(true);
functionSaveFunctionAction.setId("PISaveFunction"); //$NON-NLS-1$
functionSaveFunctionAction.setText(Messages.getString("CallVisualiser.SaveDataForFunction")); //$NON-NLS-1$
}
private class SharedLabelProvider extends LabelProvider implements ITableLabelProvider {
Table table;
public SharedLabelProvider(Table table) {
super();
this.table = table;
}
public String getColumnText(Object element, int columnIndex) {
if ( !(element instanceof GfcFunctionItem)
&& !(element instanceof CallerCalleeItem))
return ""; //$NON-NLS-1$
int columnId = ((Integer) this.table.getColumn(columnIndex).getData()).intValue();
GfcFunctionItem item = null;
if (element instanceof GfcFunctionItem)
item = (GfcFunctionItem)element;
else
item = ((CallerCalleeItem)element).item;
switch (columnId)
{
case COLUMN_ID_CALLEE_PERCENT:
case COLUMN_ID_CALLER_PERCENT:
{
double percent;
if (element instanceof CallerCalleeItem)
percent = ((CallerCalleeItem)element).percent;
else
percent = 0.0;
// Percent load string
return (new DecimalFormat(Messages.getString("CallVisualiser.shortDecimalFormat"))).format(percent); //$NON-NLS-1$
}
case COLUMN_ID_FUNCTION:
{
// Function
return item.name;
}
case COLUMN_ID_START_ADDR:
{
// Function start
return Long.toHexString(item.address);
}
case COLUMN_ID_IN_BINARY:
{
// Binary
String binary = item.dllName;
int index = binary.lastIndexOf('\\');
if (index == -1)
return binary;
else
return binary.substring(index + 1);
}
case COLUMN_ID_IN_BINARY_PATH:
{
// Path
String binary = item.dllName;
int index = binary.lastIndexOf('\\');
if (index == -1)
return ""; //$NON-NLS-1$
else
return binary.substring(0, index);
}
case COLUMN_ID_IS_CALLED:
{
// Percent load string
return (new DecimalFormat(Messages.getString("CallVisualiser.decimalFormat"))).format(myTrace.getAbsoluteTraditionalPercentageFor(item)); //$NON-NLS-1$
}
case COLUMN_ID_IS_CALLER:
{
// Percent load string
return (new DecimalFormat(Messages.getString("CallVisualiser.decimalFormat"))).format(myTrace.getAbsoluteCallerPercentageFor(item)); //$NON-NLS-1$
}
case COLUMN_ID_RECURSIVE_CALL:
{
// Percent load string
return (new DecimalFormat(Messages.getString("CallVisualiser.decimalFormat"))).format(myTrace.getRecursiveCallerPrecentageFor(item)); //$NON-NLS-1$
}
case COLUMN_ID_IS_CALLED_COUNT:
{
// Sample count
int samples;
if (element instanceof CallerCalleeItem)
samples = ((CallerCalleeItem)element).samples;
else
samples = item.isCalledCount();
return String.valueOf(samples);
}
case COLUMN_ID_IS_CALLER_COUNT:
{
// Sample count
int samples;
if (element instanceof CallerCalleeItem)
samples = ((CallerCalleeItem)element).samples;
else
samples = item.isCallerCount();
return String.valueOf(samples);
}
default:
{
break;
}
}
// should never get here
return ""; //$NON-NLS-1$
}
public Image getColumnImage(Object element, int columnIndex) {
return null;
}
}
public void selectFunction(String functionName)
{
}
public void setStartAndEnd(int start, int end)
{
if (this.myTrace == null)
return;
this.curStart = start;
this.curEnd = end;
needsRefresh = true;
if (isPageActive){
setTimeframeJob.cancel();
setTimeframeJob.schedule();
}
}
private static class CallerCalleeItem {
GfcFunctionItem item;
double percent;
int samples;
}
public void setCallerListToFunctionsThatCallThisFunction(GfcFunctionItem function)
{
if (function == null) {
this.callerList = null;
return;
}
GfcFunctionItem[] list = function.getCallerList();
Double[] perc = function.getCallerPercentages();
this.callerList = new CallerCalleeItem[list.length];
for (int i = 0; i < list.length; i++)
{
this.callerList[i] = new CallerCalleeItem();
this.callerList[i].item = list[i];
this.callerList[i].percent = perc[i];
this.callerList[i].samples = (int) (perc[i] * function.isCalledCount() + 0.5) / 100;
}
}
public void setCalleeListToFunctionsThisFunctionCalls(GfcFunctionItem function)
{
if (function == null) {
this.calleeList = null;
return;
}
GfcFunctionItem[] list = function.getCalleeList();
Double[] perc = function.getCalleePercentages();
this.calleeList = new CallerCalleeItem[list.length];
for (int i = 0; i < list.length; i++)
{
this.calleeList[i] = new CallerCalleeItem();
this.calleeList[i].item = list[i];
this.calleeList[i].percent = perc[i];
this.calleeList[i].samples = (int) (perc[i] * function.isCallerCount() + 0.5) / 100;
}
}
public void action(String actionString) {
if (actionString.equals("copy")) //$NON-NLS-1$
{
actionCopyOrSave(true, currentMenuTable, CHECKBOX_NONE, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
else if (actionString.equals("copyTable")) //$NON-NLS-1$
{
actionCopyOrSave(true, currentMenuTable, CHECKBOX_NONE, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
else if (actionString.equals("copyFunction")) //$NON-NLS-1$
{
actionCopyOrSaveFunction(true, "\t"); //$NON-NLS-1$
return;
}
else if (actionString.equals("saveTable")) //$NON-NLS-1$
{
actionCopyOrSave(false, currentMenuTable, CHECKBOX_NONE, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
return;
}
else if (actionString.equals("saveFunction")) //$NON-NLS-1$
{
actionCopyOrSaveFunction(false, ","); //$NON-NLS-1$
return;
}
else if (actionString.equals("saveSamples")) //$NON-NLS-1$
{
SaveSampleString saveSampleString = new SaveSampleString();
actionSaveSamples(saveSampleString); //$NON-NLS-1$
return;
}
else if (actionString.equals("saveTableTest")) //$NON-NLS-1$
{
// copy save file contents to the clipboard for easy viewing
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
SaveTableString getString = new SaveTableString(currentMenuTable, CHECKBOX_NONE, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
String copyString = getString.getData();
StringSelection contents = new StringSelection(copyString);
cb.setContents(contents, contents);
return;
}
else if (actionString.equals("saveFunctionTest")) //$NON-NLS-1$
{
// copy save file contents to the clipboard for easy viewing
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
SaveFunctionString getString = new SaveFunctionString(","); //$NON-NLS-1$
String copyString = getString.getData();
StringSelection contents = new StringSelection(copyString);
cb.setContents(contents, contents);
return;
}
}
/*
* TableViewer sorter for the called-by and called function tableviewers
*/
private class SharedSorter extends ViewerSorter {
// sort direction
private boolean sortAscending;
// last column sorted
private int column = -1;
/*
* decide on which column to sort by, and the sort ordering
*/
public void doSort(int column) {
// ignore the column passed in and use the id set by the column selection handler
if (column == this.column) {
// sort in other order
sortAscending = !sortAscending;
} else {
switch (column) {
case COLUMN_ID_FUNCTION:
case COLUMN_ID_START_ADDR:
case COLUMN_ID_IN_BINARY:
case COLUMN_ID_IN_BINARY_PATH:
{
// sort in ascending order
sortAscending = true;
break;
}
case COLUMN_ID_IS_CALLED:
case COLUMN_ID_IS_CALLER:
case COLUMN_ID_RECURSIVE_CALL:
case COLUMN_ID_CALLER_PERCENT:
case COLUMN_ID_CALLEE_PERCENT:
case COLUMN_ID_IS_CALLED_COUNT:
case COLUMN_ID_IS_CALLER_COUNT:
{
// sort in descending order
sortAscending = false;
break;
}
default:
{
// ignore the column
return;
}
}
this.column = column;
}
}
/*
* compare two items from a table column
*/
public int compare(Viewer viewer, Object e1, Object e2) {
int comparison = 0;
GfcFunctionItem item1 = null;
GfcFunctionItem item2 = null;
CallerCalleeItem ccItem1 = null;
CallerCalleeItem ccItem2 = null;
if (e1 instanceof GfcFunctionItem) {
item1 = (GfcFunctionItem) e1;
item2 = (GfcFunctionItem) e2;
} else {
ccItem1 = (CallerCalleeItem)e1;
ccItem2 = (CallerCalleeItem)e2;
item1 = ccItem1.item;
item2 = ccItem2.item;
}
switch (column) {
case COLUMN_ID_CALLER_PERCENT:
case COLUMN_ID_CALLEE_PERCENT:
{
double percent1;
double percent2;
if (e1 instanceof GfcFunctionItem) {
percent1 = 0.0;
percent2 = 0.0;
} else {
percent1 = ccItem1.percent;
percent2 = ccItem2.percent;
}
comparison = percent1 > percent2 ? 1 : -1;
break;
}
case COLUMN_ID_FUNCTION:
{
comparison = this.getComparator().compare(item1.name, item2.name);
break;
}
case COLUMN_ID_START_ADDR:
{
comparison = (item1.address > item2.address) ? 1 : -1;
break;
}
case COLUMN_ID_IN_BINARY:
{
int index;
String name1 = item1.dllName;
index = name1.lastIndexOf('\\');
if (index != -1)
name1 = name1.substring(index);
String name2 = item2.dllName;
index = name2.lastIndexOf('\\');
if (index != -1)
name2 = name2.substring(index);
comparison = this.getComparator().compare(name1, name2);
break;
}
case COLUMN_ID_IN_BINARY_PATH:
{
int index;
String name1 = item1.dllName;
index = name1.lastIndexOf('\\');
if (index == -1)
name1 = ""; //$NON-NLS-1$
else
name1 = name1.substring(0, index);
String name2 = item2.dllName;
index = name2.lastIndexOf('\\');
if (index == -1)
name2 = ""; //$NON-NLS-1$
else
name2 = name2.substring(0, index);
comparison = this.getComparator().compare(name1, name2);
break;
}
case COLUMN_ID_IS_CALLED:
{
// actual sample count used as a proxy for the percentage
comparison = item1.isCalledCount() - item2.isCalledCount();
break;
}
case COLUMN_ID_IS_CALLER:
{
// actual sample count used as a proxy for the percentage
comparison = item1.isCallerCount() - item2.isCallerCount();
break;
}
case COLUMN_ID_RECURSIVE_CALL:
{
comparison = myTrace.getRecursiveCallerPrecentageFor(item1) >
myTrace.getRecursiveCallerPrecentageFor(item2) ? 1 : -1;
break;
}
case COLUMN_ID_IS_CALLED_COUNT:
{
if (e1 instanceof GfcFunctionItem) {
comparison = item1.isCalledCount() - item2.isCalledCount();
} else {
comparison = ccItem1.samples - ccItem2.samples;
}
break;
}
case COLUMN_ID_IS_CALLER_COUNT:
{
if (e1 instanceof GfcFunctionItem) {
comparison = item1.isCallerCount() - item2.isCallerCount();
} else {
comparison = ccItem1.samples - ccItem2.samples;
}
break;
}
default:
{
break;
}
}
// for descending order, reverse the sense of the compare
if (!sortAscending)
comparison = -comparison;
return comparison;
}
public boolean getSortAscending() {
return sortAscending;
}
public void setSortAscending(boolean sortAscending) {
this.sortAscending = sortAscending;
}
public int getColumnID() {
return column;
}
}
public void sortAndRefresh(TableViewer tableViewer, TableColumn tableColumn)
{
Table table = tableViewer.getTable();
int columnID = ((Integer) tableColumn.getData()).intValue();
if (table.getItemCount() == 0)
return;
// sort by selected columnID
((SharedSorter) tableViewer.getSorter()).doSort(columnID);
table.setSortColumn(tableColumn);
table.setSortDirection(((SharedSorter) tableViewer.getSorter()).getSortAscending() ? SWT.UP : SWT.DOWN);
tableViewer.refresh();
}
private class CalledByColumnSelectionHandler extends SelectionAdapter
{
public void widgetSelected(SelectionEvent e)
{
if (!(e.widget instanceof TableColumn))
return;
sortAndRefresh(callerTableViewer, (TableColumn) e.widget);
}
}
private class CalledColumnSelectionHandler extends SelectionAdapter
{
public void widgetSelected(SelectionEvent e)
{
if (!(e.widget instanceof TableColumn))
return;
sortAndRefresh(calleeTableViewer, (TableColumn) e.widget);
}
}
private class CheckboxColumnSelectionHandler extends SelectionAdapter
{
public void widgetSelected(SelectionEvent e)
{
if (!(e.widget instanceof TableColumn))
return;
sortAndRefresh(currentFunctionTableViewer, (TableColumn) e.widget);
}
}
public PIPageEditor getPageEditor()
{
return this.pageEditor;
}
public int getPageIndex()
{
return this.pageIndex;
}
private MenuItem getCopyFunctionItem(Menu menu, boolean enabled) {
MenuItem copyFunctionItem = new MenuItem(menu, SWT.PUSH);
copyFunctionItem.setText(Messages.getString("CallVisualiser.CopyDataForFunction")); //$NON-NLS-1$
copyFunctionItem.setEnabled(enabled);
if (enabled) {
copyFunctionItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
action("copyFunction"); //$NON-NLS-1$
}
});
}
return copyFunctionItem;
}
private MenuItem getSaveFunctionItem(Menu menu, boolean enabled) {
MenuItem saveFunctionItem = new MenuItem(menu, SWT.PUSH);
saveFunctionItem.setText(Messages.getString("CallVisualiser.SaveDataForFunction")); //$NON-NLS-1$
saveFunctionItem.setEnabled(enabled);
if (enabled) {
saveFunctionItem.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
action("saveFunction"); //$NON-NLS-1$
}
});
}
return saveFunctionItem;
}
private void doSourceLookup(Table mytable) {
// source look up for selected items
if ((mytable.getItemCount() == 0) || (mytable.getSelectionCount() == 0))
return;
TableItem selectedItem = mytable.getSelection()[0];
Object selectedData = selectedItem.getData();
String functionName = null;
String binaryName = null;
if (selectedData instanceof GfcFunctionItem) {
GfcFunctionItem functionItem = (GfcFunctionItem) selectedData;
functionName = functionItem.name;
binaryName = functionItem.dllName;
} else if (selectedData instanceof CallerCalleeItem) {
CallerCalleeItem callerCalleeItem = (CallerCalleeItem) selectedData;
functionName = callerCalleeItem.item.name;
binaryName = callerCalleeItem.item.dllName;
}
if (functionName != null && binaryName != null)
{
SourceLookup.getInstance().lookupAndopenEditorWithHighlight(functionName , binaryName);
}
}
// class to pass the function caller/callee data to the save wizard
private class SaveFunctionString implements ISaveTable {
private String separator;
public SaveFunctionString(String separator) {
this.separator = separator;
}
public String getData() {
return copyFunction(separator);
}
}
private void actionCopyOrSaveFunction(boolean doCopy, String separator)
{
// one function must be selected
if (currentFunctionTable.getSelectionCount() != 1)
return;
// copy one function's caller and callee data to the clipboard or save to a file
if (doCopy) {
// change the clipboard contents
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
String copyString = copyFunction(separator);
StringSelection contents = new StringSelection(copyString);
cb.setContents(contents, contents);
} else {
SaveFunctionString getString = new SaveFunctionString(separator);
WizardDialog dialog;
Wizard w = new SaveTableWizard(getString);
dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), w);
dialog.open();
}
}
private String copyFunction(String separator)
{
// one function must be selected
if (currentFunctionTable.getSelectionCount() != 1)
return ""; //$NON-NLS-1$
String copyString = ""; //$NON-NLS-1$
// create the multiple table heading line (e.g., "Selected Function Callers")
// space them out based on how many columns are in their table
if (currentFunctionTable.getData() instanceof String) {
copyString += (String) (currentFunctionTable.getData());
}
for (int j = 0; j < currentFunctionTable.getColumnCount(); j++) {
copyString += separator;
}
if (callerTable.getData() instanceof String) {
copyString += (String) (callerTable.getData());
}
for (int j = 0; j < callerTable.getColumnCount(); j++) {
copyString += separator;
}
if (calleeTable.getData() instanceof String) {
copyString += (String) (calleeTable.getData());
}
for (int j = 0; j < calleeTable.getColumnCount(); j++) {
copyString += separator;
}
copyString += "\n"; //$NON-NLS-1$
// create the multiple table column headings
copyString += copyHeading(currentFunctionTable, CHECKBOX_NONE, separator, separator); //$NON-NLS-1$
copyString += copyHeading(callerTable, CHECKBOX_NONE, separator, separator); //$NON-NLS-1$
copyString += copyHeading(calleeTable, CHECKBOX_NONE, separator, "\n"); //$NON-NLS-1$
// determine the row, column count, and column ordering in each table
// NOTE: the first table in the copy will contain the function, and it only its
// one selected line will be shown
int rowCount0 = 1;
int columnCount0 = currentFunctionTable.getColumnCount();
int[] columnOrder0 = currentFunctionTable.getColumnOrder();
boolean[] isHex0 = (boolean[]) currentFunctionTable.getData("isHex"); //$NON-NLS-1$
String emptyRow0 = ""; //$NON-NLS-1$
int rowCount1 = callerTable.getItemCount();
int columnCount1 = callerTable.getColumnCount();
int[] columnOrder1 = callerTable.getColumnOrder();
boolean[] isHex1 = (boolean[]) callerTable.getData("isHex"); //$NON-NLS-1$
String emptyRow1 = ""; //$NON-NLS-1$
int rowCount2 = calleeTable.getItemCount();
int columnCount2 = calleeTable.getColumnCount();
int[] columnOrder2 = calleeTable.getColumnOrder();
boolean[] isHex2 = (boolean[]) calleeTable.getData("isHex"); //$NON-NLS-1$
String emptyRow2 = ""; //$NON-NLS-1$
// determine the number of multiple table rows (max of any table's rows)
int rowCount = rowCount0 >= rowCount1 ? rowCount0 : rowCount1;
rowCount = rowCount2 > rowCount ? rowCount2 : rowCount;
// generate empty row strings, to speed things up
if (rowCount0 < rowCount) {
for (int j = 0; j < columnCount0 - 1; j++) {
emptyRow0 += separator;
}
}
if (rowCount1 < rowCount) {
for (int j = 0; j < columnCount1; j++) {
emptyRow1 += separator;
}
}
if (rowCount2 < rowCount) {
for (int j = 0; j < columnCount2; j++) {
emptyRow2 += separator;
}
}
// generate the rows
for (int i = 0; i < rowCount; i++) {
if (i < 1) {
copyString += copyRow(isHex0, currentFunctionTable.getItem(currentFunctionTable.getSelectionIndex()),
CHECKBOX_NONE, columnCount0, columnOrder0, separator);
} else {
copyString += emptyRow0;
}
if (i < rowCount1) {
copyString += separator + copyRow(isHex1, callerTable.getItem(i), CHECKBOX_NONE, columnCount1, columnOrder1, separator);
} else {
// NOTE: if this is the last table, or the 3rd table has nothing but empty
// rows left, we may not need to fill in these fields
copyString += emptyRow1;
}
if (i < rowCount2) {
copyString += separator + copyRow(isHex2, calleeTable.getItem(i), CHECKBOX_NONE, columnCount2, columnOrder2, separator);
} else {
// NOTE: we may not need to fill in the empty fields of the last table
copyString += emptyRow2;
}
copyString += "\n"; //$NON-NLS-1$
}
return copyString;
}
private void createSetTimeframeJob() {
//this functionality used to be in the setStartEnd() method
//but now the long-running calculations are in a background job
//and the short-running refresh of table viewers is done in the UI thread
setTimeframeJob = new Job("Updating function hierarchy..."){
@Override
protected IStatus run(IProgressMonitor monitor) {
//run the time consuming calculations in the background
if (myTrace == null){
return Status.CANCEL_STATUS;
}
needsRefresh = false;
myTrace.parseEntries(curStart, curEnd);
functionArray = myTrace.getEntriesSorted(GfcTrace.SORT_BY_TOTAL_LOAD);
return Status.OK_STATUS;
}
};
setTimeframeJob.addJobChangeListener(new JobChangeAdapter() {
public void done(IJobChangeEvent event) {
if (event.getResult().isOK()) {
Display.getDefault().syncExec( new Runnable() {
public void run () {
if (!currentFunctionTableViewer.getControl().isDisposed()){
//updating the table viewers has to be done in the UI thread (this operation doesn't take long)
currentFunctionTableViewer.setInput(functionArray);
updateCallerCalleeTables(null);
Table table = currentFunctionTableViewer.getTable();
if (table.getItemCount() == 0)
return;
if (table.getSortColumn() == null) {
table.setSortColumn(currentFunctionDefaultColumn);
table.setSortDirection(SWT.UP);
} else {
// use the user's preferred sort column, if any
boolean sortAscending = !((SharedSorter) currentFunctionTableViewer.getSorter()).getSortAscending();
((SharedSorter) currentFunctionTableViewer.getSorter()).setSortAscending(sortAscending);
}
sortAndRefresh(currentFunctionTableViewer, table.getSortColumn());
}
}
});
} else {
//unsuccessful operation: we still need to refresh
needsRefresh = true;
}
}
});
setTimeframeJob.setUser(true); //show a progress dialog to the user
currentFunctionTableViewer.getControl().addDisposeListener(new DisposeListener(){
public void widgetDisposed(DisposeEvent e) {
setTimeframeJob.cancel();
}
});
}
private void createPageListeners() {
final IPageChangedListener pageChangeListener = new IPageChangedListener(){
/* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IPageChangedListener#pageChanged(org.eclipse.jface.dialogs.PageChangedEvent)
*/
public void pageChanged(PageChangedEvent event) {
isPageActive = (event.getSelectedPage() == CallVisualiser.this.curPage);//compare on reference
if (isPageActive && needsRefresh){
// if this ProfileVisualiser is the page being activated,
// check if the time frame selection needs updating
setTimeframeJob.cancel();
setTimeframeJob.schedule();
}
}
};
final IPartListener partListener = new IPartListener(){
public void partActivated(IWorkbenchPart part) {
if (part instanceof PIPageEditor){
PIPageEditor editor = (PIPageEditor) part;
isPageActive = (editor.getActivePage() == pageIndex);
if (isPageActive && needsRefresh){
setTimeframeJob.cancel();
setTimeframeJob.schedule();
}
}
}
public void partBroughtToTop(IWorkbenchPart part) {
// nothing to do
}
public void partClosed(IWorkbenchPart part) {
if (part instanceof PIPageEditor){
//remove listeners
PIPageEditor editor = (PIPageEditor) part;
editor.removePageChangedListener(pageChangeListener);
editor.getSite().getPage().removePartListener(this);
}
}
public void partDeactivated(IWorkbenchPart part) {
// nothing to do
}
public void partOpened(IWorkbenchPart part) {
// nothing to do
}
};
PIPageEditor.currentPageEditor().addPageChangedListener(pageChangeListener);
PIPageEditor.currentPageEditor().getSite().getPage().addPartListener(partListener);
}
// added to give JUnit tests access
public TableViewer getCallerViewer() {
return this.callerTableViewer;
}
// added to give JUnit tests access
public TableViewer getCurrentFunctionViewer() {
return this.currentFunctionTableViewer;
}
// added to give JUnit tests access
public TableViewer getCalleeViewer() {
return this.calleeTableViewer;
}
// added to give JUnit tests access
public void setCurrentMenuTable(Table currentMenuTable) {
this.currentMenuTable = currentMenuTable;
}
}