sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.address/src/com/nokia/carbide/cpp/pi/address/AddrFunctionTable.java
changeset 2 b9ab3b238396
child 5 844b047e260d
equal deleted inserted replaced
1:1050670c6980 2:b9ab3b238396
       
     1 /*
       
     2  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of the License "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description: 
       
    15  *
       
    16  */
       
    17 
       
    18 package com.nokia.carbide.cpp.pi.address;
       
    19 
       
    20 import java.awt.Toolkit;
       
    21 import java.awt.datatransfer.Clipboard;
       
    22 import java.awt.datatransfer.StringSelection;
       
    23 import java.awt.event.FocusEvent;
       
    24 import java.text.DecimalFormat;
       
    25 import java.util.ArrayList;
       
    26 import java.util.Arrays;
       
    27 import java.util.Comparator;
       
    28 import java.util.Enumeration;
       
    29 import java.util.Hashtable;
       
    30 import java.util.Vector;
       
    31 
       
    32 import org.eclipse.jface.viewers.CheckStateChangedEvent;
       
    33 import org.eclipse.jface.viewers.CheckboxTableViewer;
       
    34 import org.eclipse.jface.viewers.ICheckStateListener;
       
    35 import org.eclipse.jface.viewers.ISelectionChangedListener;
       
    36 import org.eclipse.jface.viewers.IStructuredContentProvider;
       
    37 import org.eclipse.jface.viewers.ITableLabelProvider;
       
    38 import org.eclipse.jface.viewers.LabelProvider;
       
    39 import org.eclipse.jface.viewers.SelectionChangedEvent;
       
    40 import org.eclipse.jface.viewers.Viewer;
       
    41 import org.eclipse.swt.SWT;
       
    42 import org.eclipse.swt.events.SelectionAdapter;
       
    43 import org.eclipse.swt.events.SelectionEvent;
       
    44 import org.eclipse.swt.graphics.Color;
       
    45 import org.eclipse.swt.graphics.Image;
       
    46 import org.eclipse.swt.layout.FormAttachment;
       
    47 import org.eclipse.swt.layout.FormData;
       
    48 import org.eclipse.swt.layout.FormLayout;
       
    49 import org.eclipse.swt.widgets.Composite;
       
    50 import org.eclipse.swt.widgets.Decorations;
       
    51 import org.eclipse.swt.widgets.Display;
       
    52 import org.eclipse.swt.widgets.Event;
       
    53 import org.eclipse.swt.widgets.Listener;
       
    54 import org.eclipse.swt.widgets.Menu;
       
    55 import org.eclipse.swt.widgets.MenuItem;
       
    56 import org.eclipse.swt.widgets.Sash;
       
    57 import org.eclipse.swt.widgets.Table;
       
    58 import org.eclipse.swt.widgets.TableColumn;
       
    59 import org.eclipse.swt.widgets.TableItem;
       
    60 
       
    61 import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
       
    62 import com.nokia.carbide.cpp.internal.pi.analyser.ProfileVisualiser;
       
    63 import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary;
       
    64 import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction;
       
    65 import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric;
       
    66 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread;
       
    67 import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold;
       
    68 import com.nokia.carbide.cpp.internal.pi.visual.Defines;
       
    69 import com.nokia.carbide.cpp.internal.pi.visual.PIEvent;
       
    70 import com.nokia.carbide.cpp.internal.pi.visual.PIVisualSharedData;
       
    71 import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
       
    72 import com.nokia.carbide.cpp.pi.util.SourceLookup;
       
    73 import com.nokia.carbide.cpp.pi.util.TableColorPalette;
       
    74 
       
    75 
       
    76 public class AddrFunctionTable extends GenericAddrTable
       
    77 {
       
    78 	// local copy of profiled binaries, which we can sort
       
    79 	// without affecting the original
       
    80 	Vector<ProfiledGeneric> profiledFunctions = new Vector<ProfiledGeneric>();
       
    81 
       
    82 	public AddrFunctionTable(GppTraceGraph myGraph, Composite parent)
       
    83 	{
       
    84 		this.myGraph = myGraph;
       
    85 		this.parent  = parent;
       
    86 	}
       
    87 
       
    88 	public void createTableViewer(int drawMode)
       
    89 	{
       
    90 		if (this.parent == null)
       
    91 			return;
       
    92 
       
    93 		// Function table:
       
    94 		//		checkbox + colored or white background
       
    95 		//  	percent load
       
    96 		//  	function name
       
    97 		//		function start address
       
    98 		//		binary containing function
       
    99 		//		path of binary containing function
       
   100 		//		sample count
       
   101 
       
   102 		// Check the drawMode, and use it to decide whether or not to show a color column
       
   103 		// or the number of samples
       
   104 		switch (drawMode)
       
   105 		{
       
   106 			case Defines.FUNCTIONS:
       
   107 			case Defines.THREADS_BINARIES_FUNCTIONS:
       
   108 			case Defines.BINARIES_FUNCTIONS:
       
   109 			case Defines.THREADS_FUNCTIONS:
       
   110 			case Defines.BINARIES_THREADS_FUNCTIONS:
       
   111 			case Defines.THREADS_FUNCTIONS_BINARIES:
       
   112 			case Defines.BINARIES_FUNCTIONS_THREADS:
       
   113 			case Defines.FUNCTIONS_THREADS:
       
   114 			case Defines.FUNCTIONS_THREADS_BINARIES:
       
   115 			case Defines.FUNCTIONS_BINARIES:
       
   116 			case Defines.FUNCTIONS_BINARIES_THREADS:
       
   117 			{
       
   118 				break;
       
   119 			}
       
   120 			default:
       
   121 				// no function table in this draw mode
       
   122 				return;
       
   123 		}
       
   124 
       
   125 		// create the table viewer
       
   126 		this.tableViewer = CheckboxTableViewer.newCheckList(this.parent,
       
   127   				SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
       
   128 
       
   129 		// add the check state handler, label provider and content provider
       
   130 		tableViewer.addCheckStateListener(new SharedCheckHandler());
       
   131 		tableViewer.setLabelProvider(new shownFunctionsLabelProvider());
       
   132 		tableViewer.setContentProvider(new shownFunctionsContentProvider());
       
   133 		tableViewer.addSelectionChangedListener(new ISelectionChangedListener() {
       
   134 			public void selectionChanged(SelectionChangedEvent arg0) {
       
   135 				if (copyAction == null)
       
   136 					return;
       
   137 
       
   138 				// when selection changes, the ability to copy may change
       
   139 				copyAction.setEnabled(table.getSelectionCount() > 0);
       
   140 				PIPageEditor.getActionBars().updateActionBars();
       
   141 			}
       
   142 		});
       
   143 
       
   144 		createDefaultActions();
       
   145 
       
   146 		// make sure the table viewer has a sorter
       
   147 		if (this.sorter == null)
       
   148 			this.sorter = new GppTableSorter();
       
   149 
       
   150 		this.table = tableViewer.getTable();
       
   151 		this.table.setRedraw(false);
       
   152 
       
   153 		// give the table a heading for use in copying and exported
       
   154 		this.table.setData(Messages.getString("AddrFunctionTable.functions")); //$NON-NLS-1$
       
   155 		
       
   156 		// create the columns
       
   157 		TableColumn column;
       
   158 
       
   159 		// data associated with the TableViewer will note which columns contain hex values
       
   160 		// Keep this in the order in which columns have been created
       
   161 		boolean[] isHex = {false, false, false, true, false, false, false};
       
   162 		this.table.setData("isHex", isHex); //$NON-NLS-1$
       
   163 
       
   164 		// select/deselect column
       
   165 		column = new TableColumn(table, SWT.CENTER);
       
   166 		column.setText(COLUMN_HEAD_SHOW);
       
   167 		column.setWidth(COLUMN_WIDTH_SHOW);
       
   168 		column.setData(new Integer(COLUMN_ID_SHOW));
       
   169 		column.setMoveable(true);
       
   170 		column.setResizable(true);
       
   171 		column.addSelectionListener(new ColumnSelectionHandler());
       
   172 
       
   173 		// percent load column
       
   174 		column = new TableColumn(table, SWT.RIGHT);
       
   175 		column.setText(COLUMN_HEAD_PERCENT_LOAD);
       
   176 		column.setWidth(COLUMN_WIDTH_PERCENT_LOAD);
       
   177 		column.setData(new Integer(COLUMN_ID_PERCENT_LOAD));
       
   178 		column.setMoveable(true);
       
   179 		column.setResizable(true);
       
   180 		column.addSelectionListener(new ColumnSelectionHandler());
       
   181 
       
   182 		// function name column
       
   183 		column = new TableColumn(table, SWT.LEFT);
       
   184 		column.setText(COLUMN_HEAD_FUNCTION);
       
   185 		column.setWidth(COLUMN_WIDTH_FUNCTION_NAME);
       
   186 		column.setData(new Integer(COLUMN_ID_FUNCTION));
       
   187 		column.setMoveable(true);
       
   188 		column.setResizable(true);
       
   189 		column.addSelectionListener(new ColumnSelectionHandler());
       
   190 
       
   191 		// function start address column
       
   192 		column = new TableColumn(table, SWT.CENTER);
       
   193 		column.setText(COLUMN_HEAD_START_ADDR);
       
   194 		column.setWidth(COLUMN_WIDTH_START_ADDRESS);
       
   195 		column.setData(new Integer(COLUMN_ID_START_ADDR));
       
   196 		column.setMoveable(true);
       
   197 		column.setResizable(true);
       
   198 		column.addSelectionListener(new ColumnSelectionHandler());
       
   199 
       
   200 		// binary containing function column
       
   201 		column = new TableColumn(table, SWT.LEFT);
       
   202 		column.setText(COLUMN_HEAD_IN_BINARY);
       
   203 		column.setWidth(COLUMN_WIDTH_IN_BINARY);
       
   204 		column.setData(new Integer(COLUMN_ID_IN_BINARY));
       
   205 		column.setMoveable(true);
       
   206 		column.setResizable(true);
       
   207 		column.addSelectionListener(new ColumnSelectionHandler());
       
   208 
       
   209 		// path to binary containing function column
       
   210 		column = new TableColumn(table, SWT.LEFT);
       
   211 		column.setText(COLUMN_HEAD_IN_BINARY_PATH);
       
   212 		column.setWidth(COLUMN_WIDTH_IN_BINARY_PATH);
       
   213 		column.setData(new Integer(COLUMN_ID_IN_BINARY_PATH));
       
   214 		column.setMoveable(true);
       
   215 		column.setResizable(true);
       
   216 		column.addSelectionListener(new ColumnSelectionHandler());
       
   217 
       
   218 		// sample count column
       
   219 		column = new TableColumn(table, SWT.CENTER);
       
   220 		column.setText(COLUMN_HEAD_SAMPLE_COUNT);
       
   221 		column.setWidth(COLUMN_WIDTH_SAMPLE_COUNT);
       
   222 		column.setData(new Integer(COLUMN_ID_SAMPLE_COUNT));
       
   223 		column.setMoveable(true);
       
   224 		column.setResizable(true);
       
   225 		column.addSelectionListener(new ColumnSelectionHandler());
       
   226 
       
   227 		// listen for mouse clicks: to select a row, pop up a menu, etc.
       
   228 		table.addMouseListener(new TableMouseListener());
       
   229 
       
   230 		// listen for key sequences such as Ctrl-A and Ctrl-C
       
   231 		table.addKeyListener(new TableKeyListener());
       
   232 
       
   233 		table.addFocusListener(new AddrTableFocusListener());
       
   234 
       
   235 		// add form data in case later we add a sash to the right
       
   236 		FormData viewerData = new FormData();
       
   237 		viewerData.top    = new FormAttachment(0);
       
   238 		viewerData.bottom = new FormAttachment(100);
       
   239 		viewerData.left   = new FormAttachment(0);
       
   240 		viewerData.right  = new FormAttachment(100);
       
   241 		table.setLayoutData(viewerData);
       
   242 		table.setLayout(new FormLayout());
       
   243 
       
   244 		table.setHeaderVisible(true);
       
   245 		table.setLinesVisible(true);
       
   246 		table.setRedraw(true);
       
   247 	}
       
   248 
       
   249 	public void setTableViewer(CheckboxTableViewer tableViewer)
       
   250 	{
       
   251 		this.tableViewer = tableViewer;
       
   252 
       
   253 		if (tableViewer == null)
       
   254 			this.table = null;
       
   255 	}
       
   256 
       
   257 	public void setTableViewer(int drawMode)
       
   258 	{
       
   259 		if (this.parent == null)
       
   260 			return;
       
   261 
       
   262 		createTableViewer(drawMode);
       
   263 
       
   264 		// sort by sample count
       
   265 		this.sortColumn = COLUMN_ID_SAMPLE_COUNT;
       
   266 		this.sortAscending = false;
       
   267 
       
   268 		// profiledFunctions and tableItemData contain one entry per table row
       
   269 		updateProfiledAndItemData(false);
       
   270 		quickSort(sortColumn, profiledFunctions);
       
   271 
       
   272 		// initially, all rows are selected
       
   273 		this.tableViewer.setAllChecked(true);
       
   274 	}
       
   275 
       
   276 	public void refreshTableViewer()
       
   277 	{
       
   278 		if (this.tableViewer == null)
       
   279 			return;
       
   280 
       
   281 		this.tableViewer.setInput(tableItemData);
       
   282 		
       
   283 		addColor(this.myGraph.getDrawMode());
       
   284 	}
       
   285 	
       
   286 	public void addColor(int drawMode)
       
   287 	{
       
   288 		if (this.tableViewer == null)
       
   289 			return;
       
   290 
       
   291 		// make sure that this table's colors are being shown
       
   292 		if (   (drawMode != Defines.FUNCTIONS)
       
   293 			&& (drawMode != Defines.THREADS_FUNCTIONS)
       
   294 			&& (drawMode != Defines.THREADS_BINARIES_FUNCTIONS)
       
   295 			&& (drawMode != Defines.BINARIES_FUNCTIONS)
       
   296 			&& (drawMode != Defines.BINARIES_THREADS_FUNCTIONS))
       
   297 			return;
       
   298 
       
   299 		ProfiledGeneric pGeneric;
       
   300 
       
   301 		TableItem[] items = this.table.getItems();
       
   302 
       
   303 		for (int i = 0; i < items.length; i++) {
       
   304 			pGeneric = (ProfiledGeneric) items[i].getData();
       
   305 //			Color color = ((GppTrace)this.myGraph.getTrace()).getFunctionColorPalette().getColor(pGeneric.getNameString());
       
   306 			items[i].setBackground(COLOR_COLUMN_INDEX, pGeneric.getColor());
       
   307 		}
       
   308 
       
   309 		table.redraw();
       
   310 	}
       
   311 	
       
   312 	public void removeColor(int drawMode)
       
   313 	{
       
   314 		if (this.tableViewer == null)
       
   315 			return;
       
   316 
       
   317 		// make sure that this table's colors should not be shown
       
   318 		if (   (drawMode == Defines.FUNCTIONS)
       
   319 			|| (drawMode == Defines.THREADS_FUNCTIONS)
       
   320 			|| (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
       
   321 			|| (drawMode == Defines.BINARIES_FUNCTIONS)
       
   322 			|| (drawMode == Defines.BINARIES_THREADS_FUNCTIONS))
       
   323 			return;
       
   324 
       
   325 		TableItem[] items = this.table.getItems();
       
   326 
       
   327 		for (int i = 0; i < items.length; i++) {
       
   328 			items[i].setBackground(COLOR_COLUMN_INDEX, this.parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
       
   329 		}
       
   330 
       
   331 		table.redraw();
       
   332 	}
       
   333 
       
   334 	private static class shownFunctionsContentProvider implements IStructuredContentProvider {
       
   335 
       
   336 		public shownFunctionsContentProvider() {
       
   337 			super();
       
   338 		}
       
   339 
       
   340 		public Object[] getElements(Object inputElement) {
       
   341 			return ((Vector) inputElement).toArray();
       
   342 		}
       
   343 
       
   344 		public void dispose() {
       
   345 		}
       
   346 
       
   347 		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
       
   348 		}
       
   349 	}
       
   350 
       
   351 	private class shownFunctionsLabelProvider extends LabelProvider implements ITableLabelProvider {
       
   352 
       
   353 		public shownFunctionsLabelProvider() {
       
   354 			super();
       
   355 		}
       
   356 
       
   357 		public String getColumnText(Object element, int columnIndex) {
       
   358 			int columnId = ((Integer) table.getColumn(columnIndex).getData()).intValue();
       
   359 
       
   360 			if (element instanceof ProfiledThreshold) {
       
   361 				ProfiledThreshold pThreshold = (ProfiledThreshold) element;
       
   362 				switch (columnId)
       
   363 				{
       
   364 					case COLUMN_ID_SHOW:
       
   365 					{
       
   366 						return SHOW_ITEM_VALUE;
       
   367 					}
       
   368 					case COLUMN_ID_PERCENT_LOAD:
       
   369 					{
       
   370 						// Percent load string
       
   371 						double startTime = PIPageEditor.currentPageEditor().getStartTime();
       
   372 						double endTime   = PIPageEditor.currentPageEditor().getEndTime();
       
   373 						if (   (startTime == -1)
       
   374 							|| (endTime   == -1)
       
   375 							|| (startTime == endTime)) {
       
   376 							pThreshold.setAverageLoadValueString(myGraph.getGraphIndex(), ""); //$NON-NLS-1$
       
   377 						} else {
       
   378 							float load = (float) (pThreshold.getSampleCount(myGraph.getGraphIndex())/(endTime - startTime)/10.0);
       
   379 							
       
   380 							if (load < 0.005)
       
   381 								pThreshold.setAverageLoadValueString(myGraph.getGraphIndex(), Messages.getString("AddrFunctionTable.zeroFormat")); //$NON-NLS-1$
       
   382 							else
       
   383 								pThreshold.setAverageLoadValueString(myGraph.getGraphIndex(), load);
       
   384 						}
       
   385 						return pThreshold.getAverageLoadValueString(myGraph.getGraphIndex());
       
   386 					}
       
   387 					case COLUMN_ID_FUNCTION:
       
   388 					{
       
   389 						DecimalFormat timeFormat = new DecimalFormat(Messages.getString("AddrFunctionTable.decimalFormat")); //$NON-NLS-1$
       
   390 						int count = pThreshold.getItemCount(myGraph.getGraphIndex());
       
   391 
       
   392 						return count + (count > 1 ? Messages.getString("AddrFunctionTable.threshold1") : Messages.getString("AddrFunctionTable.threshold2"))   //$NON-NLS-1$ //$NON-NLS-2$
       
   393 								+ timeFormat.format((Double)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdLoadThread") * 100.0) + Messages.getString("AddrFunctionTable.threshold3")  //$NON-NLS-1$ //$NON-NLS-2$
       
   394 								+ (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction") + Messages.getString("AddrFunctionTable.threshold4"); //$NON-NLS-1$ //$NON-NLS-2$	
       
   395 					}
       
   396 					case COLUMN_ID_SAMPLE_COUNT:
       
   397 					{
       
   398 						// Sample count
       
   399 						return String.valueOf(pThreshold.getSampleCount(myGraph.getGraphIndex()));
       
   400 					}
       
   401 					default:
       
   402 					{
       
   403 						return ""; //$NON-NLS-1$
       
   404 					}
       
   405 				}
       
   406 			}
       
   407 
       
   408 			if (!(element instanceof ProfiledFunction))
       
   409 				return ""; //$NON-NLS-1$
       
   410 
       
   411 			ProfiledFunction profiledItem = (ProfiledFunction) element;
       
   412 
       
   413 			switch (columnId)
       
   414 			{
       
   415 				case COLUMN_ID_SHOW:
       
   416 				{
       
   417 					return SHOW_ITEM_VALUE;
       
   418 				}
       
   419 				case COLUMN_ID_PERCENT_LOAD:
       
   420 				{
       
   421 					// Percent load string
       
   422 					return profiledItem.getAverageLoadValueString(myGraph.getGraphIndex());
       
   423 				}
       
   424 				case COLUMN_ID_FUNCTION:
       
   425 				{
       
   426 					// Function
       
   427 					return (profiledItem.getNameString());
       
   428 				}
       
   429 				case COLUMN_ID_START_ADDR:
       
   430 				{
       
   431 					// Function start
       
   432 					return (Long.toHexString(profiledItem.getFunctionAddress()));
       
   433 				}
       
   434 				case COLUMN_ID_IN_BINARY:
       
   435 				{
       
   436 					// Binary
       
   437 					String binary = profiledItem.getFunctionBinaryName();
       
   438 					int index = binary.lastIndexOf('\\');
       
   439 					if (index == -1)
       
   440 						return binary;
       
   441 					else
       
   442 						return binary.substring(index + 1);
       
   443 				}
       
   444 				case COLUMN_ID_IN_BINARY_PATH:
       
   445 				{
       
   446 					// Path
       
   447 					String binary = profiledItem.getFunctionBinaryName();
       
   448 					int index = binary.lastIndexOf('\\');
       
   449 					if (index == -1)
       
   450 						return ""; //$NON-NLS-1$
       
   451 					else
       
   452 						return binary.substring(0, index);
       
   453 				}
       
   454 				case COLUMN_ID_SAMPLE_COUNT:
       
   455 				{
       
   456 					// Sample count
       
   457 					return String.valueOf(profiledItem.getSampleCount(myGraph.getGraphIndex()));
       
   458 				}
       
   459 				default:
       
   460 				{
       
   461 					break;
       
   462 				}
       
   463 			}
       
   464 			// should never get here
       
   465 			return ""; //$NON-NLS-1$
       
   466 		}
       
   467 
       
   468 		public Image getColumnImage(Object element, int columnIndex) {
       
   469 			return null;
       
   470 		}
       
   471 	}
       
   472 
       
   473     public void action(String actionString)
       
   474 	{
       
   475 		int graphIndex = this.myGraph.getGraphIndex();
       
   476 
       
   477 		if (   actionString.equals("add") //$NON-NLS-1$
       
   478 			|| actionString.equals("remove")) //$NON-NLS-1$
       
   479 	    {
       
   480 			actionAddRemove(actionString, graphIndex);
       
   481 			return;
       
   482 	    }
       
   483 		else if (   actionString.equals("addall") //$NON-NLS-1$
       
   484 				 || actionString.equals("removeall")) //$NON-NLS-1$
       
   485 	    {
       
   486 			actionAddRemoveAll(actionString, graphIndex);
       
   487 			return;
       
   488 	    }
       
   489 		else if (actionString.equals("recolor")) //$NON-NLS-1$
       
   490 		{
       
   491 			actionRecolor();
       
   492 			return;
       
   493 		}
       
   494 	    else if (actionString.equals("copy")) //$NON-NLS-1$
       
   495 	    {
       
   496 	    	actionCopyOrSave(true, this.table, CHECKBOX_NO_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
       
   497 	        return;
       
   498 	    }
       
   499 	    else if (actionString.equals("copyTable")) //$NON-NLS-1$
       
   500 	    {
       
   501 	    	actionCopyOrSave(true, this.table, CHECKBOX_NO_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
       
   502 	        return;
       
   503 	    }
       
   504 	    else if (actionString.equals("copyDrilldown")) //$NON-NLS-1$
       
   505 	    {
       
   506 	    	actionCopyOrSaveDrilldown(true, "\t"); //$NON-NLS-1$
       
   507 	        return;
       
   508 	    }
       
   509 	    else if (actionString.equals("saveTable")) //$NON-NLS-1$
       
   510 	    {
       
   511 	    	actionCopyOrSave(false, this.table, CHECKBOX_NO_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
       
   512 	        return;
       
   513 	    }
       
   514 	    else if (actionString.equals("saveDrilldown")) //$NON-NLS-1$
       
   515 	    {
       
   516 	    	actionCopyOrSaveDrilldown(false, ","); //$NON-NLS-1$
       
   517 	        return;
       
   518 	    }
       
   519 	    else if (actionString.equals("saveSamples")) //$NON-NLS-1$
       
   520 	    {
       
   521 	    	SaveSampleString saveSampleString = new SaveSampleString(graphIndex, myGraph.getDrawMode());
       
   522 	    	actionSaveSamples(saveSampleString); //$NON-NLS-1$
       
   523 	        return;
       
   524 	    }
       
   525 		else if (actionString.equals("selectAll")) //$NON-NLS-1$
       
   526 	    {
       
   527 	    	actionSelectAll();
       
   528 	        return;
       
   529 	    }
       
   530 		else if (actionString.equals("doubleClick")) //$NON-NLS-1$
       
   531 	    {
       
   532 	    	copyAction.setEnabled(false);
       
   533 			PIPageEditor.getActionBars().updateActionBars();
       
   534 	        return;
       
   535 	    }
       
   536 		else if (actionString.equals("sortinfullpath")) //$NON-NLS-1$
       
   537 		{
       
   538             if (this.sortColumn == COLUMN_ID_FULL_IN_PATH)
       
   539             	// sort in other order
       
   540             	sortAscending = !sortAscending;
       
   541             else
       
   542             	// sort in ascending order
       
   543             	sortAscending = true;
       
   544             sortColumn = COLUMN_ID_FULL_IN_PATH;
       
   545             quickSort(sortColumn, profiledFunctions);
       
   546 		}
       
   547 		else if (actionString.equals("function-only")) //$NON-NLS-1$
       
   548 		{
       
   549 			actionFunction();
       
   550 			return;
       
   551 		}
       
   552 		else if (actionString.equals("function-thread")) //$NON-NLS-1$
       
   553 		{
       
   554 			actionFunctionThread();
       
   555 			return;
       
   556 		}
       
   557 		else if (actionString.equals("function-thread-binary")) //$NON-NLS-1$
       
   558 		{
       
   559 			actionFunctionThreadBinary();
       
   560 			return;
       
   561 		}
       
   562 		else if (actionString.equals("function-binary")) //$NON-NLS-1$
       
   563 		{
       
   564 			actionFunctionBinary();
       
   565 			return;
       
   566 		}
       
   567 		else if (actionString.equals("function-binary-thread")) //$NON-NLS-1$
       
   568 		{
       
   569 			actionFunctionBinaryThread();
       
   570 			return;
       
   571 		}
       
   572 		else if (   (actionString.equals("thread-only")) //$NON-NLS-1$
       
   573 				 || (actionString.equals("thread-binary")) //$NON-NLS-1$
       
   574 				 || (actionString.equals("thread-binary-function")) //$NON-NLS-1$
       
   575 				 || (actionString.equals("thread-function")) //$NON-NLS-1$
       
   576 				 || (actionString.equals("thread-function-binary"))) //$NON-NLS-1$
       
   577 		{
       
   578 			// let the thread page action handler handle it
       
   579 			this.myGraph.getThreadTable().action(actionString);
       
   580 			return;
       
   581 		}
       
   582 		else if (   (actionString.equals("binary-only")) //$NON-NLS-1$
       
   583 				 || (actionString.equals("binary-thread")) //$NON-NLS-1$
       
   584 				 || (actionString.equals("binary-thread-function")) //$NON-NLS-1$
       
   585 				 || (actionString.equals("binary-function")) //$NON-NLS-1$
       
   586 				 || (actionString.equals("binary-function-thread"))) //$NON-NLS-1$
       
   587 		{
       
   588 			// let the binary page action handler handle it
       
   589 			this.myGraph.getBinaryTable().action(actionString);
       
   590 			return;
       
   591 		}
       
   592 		else if (actionString.equals("changeThresholdFunction")) //$NON-NLS-1$
       
   593 		{
       
   594 			ProfiledThreshold threshold = this.myGraph.getThresholdFunction();
       
   595 			boolean enabled = threshold.isEnabled(graphIndex);
       
   596 
       
   597 			this.tableItemData.clear();
       
   598 			this.profiledFunctions.clear();
       
   599 			this.myGraph.getSortedFunctions().clear();
       
   600 			if (threshold.getItems(graphIndex) != null)
       
   601 				threshold.getItems(graphIndex).clear();
       
   602 			threshold.initAll();
       
   603 
       
   604 			// if this appears, it needs to be the first item, so that it is drawn at the bottom
       
   605 			myGraph.getSortedFunctions().add(threshold);
       
   606 
       
   607 			int functionThreshold = (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
       
   608 			for (int i = 0; i < this.myGraph.getGppTrace().getSortedFunctions().size(); i++) {
       
   609 				ProfiledGeneric nextElement = (ProfiledGeneric)this.myGraph.getGppTrace().getSortedFunctions().get(i);
       
   610 				if (nextElement.getTotalSampleCount() < functionThreshold) {
       
   611 					nextElement.setEnabled(graphIndex, enabled);
       
   612 					threshold.addItem(graphIndex, nextElement, 0);
       
   613 				} else {
       
   614 					tableItemData.add(nextElement);
       
   615 					profiledFunctions.add(nextElement);
       
   616 					myGraph.getSortedFunctions().add(nextElement);
       
   617 				}
       
   618 			}
       
   619 
       
   620 			if (threshold.getItemCount(graphIndex) != 0) {
       
   621 				tableItemData.add(threshold);
       
   622 				profiledFunctions.add(threshold);
       
   623 			} else {
       
   624 				// remove the threshold item
       
   625 				myGraph.getSortedFunctions().remove(0);
       
   626 			}
       
   627 			
       
   628 			refreshTableViewer();
       
   629 			threshold.setEnabled(graphIndex, enabled);
       
   630 
       
   631 			// make sure that checkboxes shown reflect the actual enabled values
       
   632 			TableItem[] tableItems = this.table.getItems();
       
   633 			for (int i = 0; i < tableItems.length; i++) {
       
   634 				if (tableItems[i].getData() instanceof ProfiledGeneric) {
       
   635 					ProfiledGeneric pGeneric = (ProfiledGeneric) tableItems[i].getData();
       
   636 					if (tableItems[i].getChecked() != pGeneric.isEnabled(graphIndex))
       
   637 						tableItems[i].setChecked(pGeneric.isEnabled(graphIndex));
       
   638 				}
       
   639 			}
       
   640 
       
   641 			this.myGraph.genericRefreshCumulativeThreadTable();
       
   642 		}
       
   643 		else if (actionString.equals("sourceLookup")) //$NON-NLS-1$
       
   644 		{
       
   645 			actionSourceLookup();
       
   646 			return;
       
   647 		}
       
   648 	    else if (actionString.equals("saveTableTest")) //$NON-NLS-1$
       
   649 	    {
       
   650 			// copy save file contents to the clipboard for easy viewing
       
   651 	        Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
       
   652 			SaveTableString getString = new SaveTableString(this.table, CHECKBOX_NO_TEXT, Messages.getString("AddrFunctionTable.comma"), "\n"); //$NON-NLS-1$ //$NON-NLS-2$
       
   653 	        String copyString = getString.getData();
       
   654 			StringSelection contents = new StringSelection(copyString);
       
   655 	        cb.setContents(contents, contents);
       
   656 	        return;
       
   657 	    }
       
   658 	    else if (actionString.equals("saveDrilldownTest")) //$NON-NLS-1$
       
   659 	    {
       
   660 			// copy save file contents to the clipboard for easy viewing
       
   661 	        Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
       
   662 	        Table[] tables = getDrillDownTables();
       
   663 	        
       
   664 	        int tableCount = 0;
       
   665 	        while (tableCount < tables.length && tables[tableCount] != null)
       
   666 	        	tableCount++;
       
   667 
       
   668 	        SaveDrillDownString getString = new SaveDrillDownString(tableCount, tables, Messages.getString("AddrFunctionTable.comma")); //$NON-NLS-1$
       
   669 	        String copyString = getString.getData();
       
   670 			StringSelection contents = new StringSelection(copyString);
       
   671 	        cb.setContents(contents, contents);
       
   672 	        return;
       
   673 	    }
       
   674 	}
       
   675 
       
   676     private void actionAddRemove(String actionString, int graphIndex)
       
   677 	{
       
   678 		ProfiledGeneric pGeneric;
       
   679 		int totalSamples = 0;
       
   680 		
       
   681 		// true for "add", false for "remove"
       
   682 		boolean addIt = actionString.equals("add"); //$NON-NLS-1$
       
   683 
       
   684 		TableItem[] selectedItems = this.table.getSelection();
       
   685 		for (int i = 0; i < selectedItems.length; i++)
       
   686 		{
       
   687 			selectedItems[i].setChecked(addIt);
       
   688 			Object item = ((TableItem)selectedItems[i]).getData();
       
   689 			if (item instanceof ProfiledGeneric)
       
   690 			{
       
   691 				pGeneric = (ProfiledGeneric)item;
       
   692 				pGeneric.setEnabled(graphIndex, addIt);
       
   693 				totalSamples += pGeneric.getSampleCount(graphIndex);
       
   694    				
       
   695    				if (item instanceof ProfiledThreshold)
       
   696    				{
       
   697    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
       
   698    					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
       
   699    					for (int j = 0; j < items.size(); j++)
       
   700    						items.get(j).setEnabled(graphIndex, addIt);
       
   701    				}
       
   702 			}
       
   703 		}
       
   704 
       
   705         // this table's set of checkbox-selected rows has changed,
       
   706 		// so propagate that information
       
   707 		Object[] selectedValues = this.tableViewer.getCheckedElements();
       
   708 		String[] nameList = new String[selectedValues.length];
       
   709 
       
   710 		for (int i = 0; i < selectedValues.length; i++)
       
   711 		{
       
   712    			if (selectedValues[i] instanceof ProfiledGeneric)
       
   713    			{
       
   714    				pGeneric = (ProfiledGeneric)selectedValues[i];
       
   715    				nameList[i] = pGeneric.getNameString();
       
   716    			}
       
   717 		}
       
   718 
       
   719 		PIVisualSharedData shared = myGraph.getSharedDataInstance();
       
   720 		shared.GPP_SelectedFunctionNames = nameList;
       
   721 
       
   722   		if (   (totalSamples != 0)
       
   723       		|| (myGraph.getDrawMode() == Defines.FUNCTIONS))
       
   724       			selectionChangeNotify();
       
   725 
       
   726   		this.table.deselectAll();
       
   727 	}
       
   728 	
       
   729 	private void actionAddRemoveAll(String actionString, int graphIndex)
       
   730 	{
       
   731 		ProfiledGeneric pGeneric;
       
   732 
       
   733 		// true for "add", false for "remove"
       
   734 		boolean addIt = actionString.equals("addall"); //$NON-NLS-1$
       
   735 
       
   736 		TableItem[] selectedItems = this.table.getItems();
       
   737 		String[] nameList = new String[selectedItems.length];
       
   738 		for (int i = 0; i < selectedItems.length; i++)
       
   739 		{
       
   740 			selectedItems[i].setChecked(addIt);
       
   741 			Object item = ((TableItem)selectedItems[i]).getData();
       
   742 			if (item instanceof ProfiledGeneric)
       
   743 			{
       
   744 				pGeneric = (ProfiledGeneric)item;
       
   745 				pGeneric.setEnabled(graphIndex, addIt);
       
   746    				nameList[i] = pGeneric.getNameString();
       
   747    				
       
   748    				if (item instanceof ProfiledThreshold)
       
   749    				{
       
   750    					ProfiledThreshold pThreshold = (ProfiledThreshold)item;
       
   751    					ArrayList<ProfiledGeneric> items = pThreshold.getItems(graphIndex);
       
   752    					for (int j = 0; j < items.size(); j++)
       
   753    						items.get(j).setEnabled(graphIndex, addIt);
       
   754    				}
       
   755 			}
       
   756 		}
       
   757 
       
   758         // this table's set of checkbox-selected rows has changed,
       
   759 		// so propagate that information
       
   760 		PIVisualSharedData shared = myGraph.getSharedDataInstance();
       
   761 		shared.GPP_SelectedFunctionNames = nameList;
       
   762 
       
   763 			selectionChangeNotify();
       
   764   		this.table.deselectAll();
       
   765 	}
       
   766 	
       
   767 	private void actionRecolor()
       
   768 	{
       
   769 		int uid    			= this.myGraph.getUid();
       
   770 		GppTrace gppTrace = this.myGraph.getGppTrace();
       
   771 
       
   772 		// recolor selected items
       
   773 		boolean didRecolor = false;
       
   774 
       
   775 		TableItem[] selectedItems = table.getSelection();
       
   776 		TableColorPalette palette = ((GppTrace)this.myGraph.getTrace()).getFunctionColorPalette();
       
   777 		for (int i = 0; i < selectedItems.length;i++)
       
   778 		{
       
   779 			if (selectedItems[i].getData() instanceof ProfiledGeneric)
       
   780 			{
       
   781 				ProfiledGeneric pGeneric = (ProfiledGeneric)selectedItems[i].getData();
       
   782 				String nameKey = pGeneric.getNameString();
       
   783 				if (palette.recolorEntryDialog(table.getShell(), nameKey))
       
   784 				{
       
   785 					Color color = palette.getColor(nameKey);
       
   786 					Color oldColor = pGeneric.getColor();
       
   787 					
       
   788 					if (color.equals(oldColor))
       
   789 						continue;
       
   790 					
       
   791 					didRecolor = true;
       
   792 					
       
   793 					if (!(pGeneric instanceof ProfiledThreshold)){
       
   794 						PIPageEditor.currentPageEditor().setDirty();
       
   795 						pGeneric.setColor(color);
       
   796 					}
       
   797 					else {
       
   798 						// for the threshold item, we must change every graph's function threshold item
       
   799 						gppTrace.getGppGraph(PIPageEditor.THREADS_PAGE,   uid).getThresholdFunction().setColor(color);
       
   800 						gppTrace.getGppGraph(PIPageEditor.BINARIES_PAGE,  uid).getThresholdFunction().setColor(color);
       
   801 						gppTrace.getGppGraph(PIPageEditor.FUNCTIONS_PAGE, uid).getThresholdFunction().setColor(color);
       
   802 					}
       
   803 				}
       
   804 
       
   805 				// recoloring should only be done in a draw mode that displays this table's colors
       
   806 				selectedItems[i].setBackground(COLOR_COLUMN_INDEX, palette.getColor(nameKey));
       
   807 			}
       
   808 		}
       
   809 		
       
   810 		if (!didRecolor)
       
   811 			return;
       
   812 
       
   813 		table.redraw();
       
   814 		this.myGraph.repaint();
       
   815 		this.myGraph.setGraphImageChanged(true);	// any selection change to drill down will change graph
       
   816 		
       
   817 		// if any other tabs are displaying this type of graph, they need to be scheduled for redrawing
       
   818 		for (int i = 0; i < 3; i++) {
       
   819 			GppTraceGraph graph = gppTrace.getGppGraph(i, uid);
       
   820 
       
   821 			if (graph == this.myGraph)
       
   822 				continue;
       
   823 
       
   824 			int drawMode = graph.getDrawMode();
       
   825 			
       
   826 			if (   (drawMode == Defines.FUNCTIONS)
       
   827 				|| (drawMode == Defines.THREADS_FUNCTIONS)
       
   828 				|| (drawMode == Defines.THREADS_BINARIES_FUNCTIONS)
       
   829 				|| (drawMode == Defines.BINARIES_FUNCTIONS)
       
   830 				|| (drawMode == Defines.BINARIES_THREADS_FUNCTIONS)) {
       
   831 				graph.getFunctionTable().addColor(drawMode);
       
   832 				graph.setGraphImageChanged(true);	// any selection change to drill down will change graph
       
   833 				graph.repaint();
       
   834 			}
       
   835 		}
       
   836 	}
       
   837 	
       
   838 	private void actionFunction()
       
   839 	{
       
   840 		// current drawMode should be FUNCTIONS, FUNCTIONS_THREADS, FUNCTIONS_THREADS_BINARIES,
       
   841 		// FUNCTIONS_BINARIES, or FUNCTIONS_BINARIES_THREADS
       
   842 		int drawMode = this.myGraph.getDrawMode();
       
   843 
       
   844 		if (   (drawMode != Defines.FUNCTIONS_THREADS)
       
   845 			&& (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
       
   846 			&& (drawMode != Defines.FUNCTIONS_BINARIES)
       
   847 			&& (drawMode != Defines.FUNCTIONS_BINARIES_THREADS))
       
   848 		{
       
   849 			// this case should be drawMode == Defines.FUNCTIONS
       
   850 			return;
       
   851 		}
       
   852 
       
   853 		setIsDrilldown(false);
       
   854 
       
   855 		// set the page's graph title
       
   856 		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
   857 		pV.getTitle().setText(Messages.getString("AddrFunctionTable.functionLoad"));  //$NON-NLS-1$
       
   858 		pV.getTitle2().setText(""); //$NON-NLS-1$
       
   859 
       
   860 		// get rid of any existing tables and sashes
       
   861 		if (this.myGraph.getLeftSash() != null) {
       
   862 			this.myGraph.getLeftSash().dispose();
       
   863 			this.myGraph.setLeftSash(null);
       
   864 
       
   865 			// detach the table from the sash
       
   866 			try {
       
   867 				FormData formData = (FormData) this.table.getLayoutData();
       
   868 				formData.right = new FormAttachment(100);
       
   869 			} catch (ClassCastException e1) {
       
   870 			}
       
   871 		}
       
   872 		if (this.myGraph.getRightSash() != null) {
       
   873 			this.myGraph.getRightSash().dispose();
       
   874 			this.myGraph.setRightSash(null);
       
   875 		}
       
   876 		if (   (this.myGraph.getThreadTable() != null)
       
   877 			&& (this.myGraph.getThreadTable().getTable() != null)) {
       
   878 			this.myGraph.getThreadTable().getTableViewer().getTable().dispose();
       
   879 			this.myGraph.getThreadTable().setTableViewer(null);
       
   880 		}
       
   881 		if (   (this.myGraph.getBinaryTable() != null)
       
   882 			&& (this.myGraph.getBinaryTable().getTable() != null)) {
       
   883 			this.myGraph.getBinaryTable().getTableViewer().getTable().dispose();
       
   884 			this.myGraph.getBinaryTable().setTableViewer(null);
       
   885 		}
       
   886 
       
   887 		// set the draw mode
       
   888 		this.myGraph.setDrawMode(Defines.FUNCTIONS);
       
   889 
       
   890 		// add colors to the rightmost table
       
   891 		addColor(Defines.FUNCTIONS);
       
   892 		
       
   893 		this.parent.layout();
       
   894 
       
   895  		this.myGraph.repaint();
       
   896 	}
       
   897 
       
   898 	private void actionFunctionBinary()
       
   899 	{
       
   900 		// current drawMode should be FUNCTIONS, FUNCTIONS_BINARIES, or FUNCTIONS_BINARIES_THREADS
       
   901 		int drawMode = this.myGraph.getDrawMode();
       
   902 		int graphIndex = this.myGraph.getGraphIndex();
       
   903 		
       
   904 		if (   drawMode != Defines.FUNCTIONS
       
   905 			&& drawMode != Defines.FUNCTIONS_BINARIES_THREADS) {
       
   906 			return;
       
   907 		}
       
   908 
       
   909 		setIsDrilldown(true);
       
   910 
       
   911 		if (drawMode == Defines.FUNCTIONS) {
       
   912 			// set the page's graph title
       
   913 			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
   914 			pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
       
   915 			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
       
   916 
       
   917 			// set the draw mode
       
   918 			this.myGraph.setDrawMode(Defines.FUNCTIONS_BINARIES);
       
   919 
       
   920 			// create the binary graph table viewer
       
   921 			AddrBinaryTable binaryTable = this.myGraph.getBinaryTable();
       
   922 			binaryTable.createTableViewer(Defines.FUNCTIONS_BINARIES);
       
   923 			binaryTable.setIsDrilldown(true);
       
   924 
       
   925 			// create a reduced set of binary entries based on enabled function entries
       
   926 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
       
   927 			Vector<ProfiledGeneric> binaries = gppTrace.setFunctionBinary(graphIndex);
       
   928 			this.myGraph.setProfiledBinaries(binaries);
       
   929 
       
   930 			// put check marks on all rows, and sort by sample count
       
   931 			binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
       
   932 			binaryTable.updateProfiledAndItemData(true);
       
   933 			binaryTable.getTableViewer().setAllChecked(true);
       
   934 			binaryTable.getTableViewer().refresh();
       
   935 
       
   936 			// remove colors where appropriate
       
   937 			removeColor(Defines.FUNCTIONS_BINARIES);
       
   938 
       
   939 			// connect the tables with a sash
       
   940 			Sash leftSash   = new Sash(this.parent, SWT.VERTICAL);
       
   941 
       
   942 			final FormData leftSashData = new FormData();
       
   943 			leftSashData.top    = new FormAttachment(0);
       
   944 			leftSashData.bottom = new FormAttachment(100);
       
   945 			leftSashData.left   = new FormAttachment(50); // middle
       
   946 			leftSash.setLayoutData(leftSashData);
       
   947 
       
   948 			final Composite sashParent = this.parent;
       
   949 			leftSash.addListener(SWT.Selection, new Listener() {
       
   950 				public void handleEvent(Event event) {
       
   951 					if (event.detail != SWT.DRAG) {
       
   952 						leftSashData.left = new FormAttachment(0, event.x);
       
   953 						sashParent.layout();
       
   954 					}
       
   955 				}
       
   956 			});
       
   957 
       
   958 			myGraph.setLeftSash(leftSash);
       
   959 
       
   960 			// attach the binary table to the sash
       
   961 			final FormData viewerData = new FormData();
       
   962 			viewerData.top    = new FormAttachment(0);
       
   963 			viewerData.bottom = new FormAttachment(100);
       
   964 			viewerData.left   = new FormAttachment(leftSash);
       
   965 			viewerData.right  = new FormAttachment(100);
       
   966 			binaryTable.getTable().setLayoutData(viewerData);
       
   967 
       
   968 			// attach the function table to the sash
       
   969 			try {
       
   970 				FormData formData = (FormData) this.table.getLayoutData();
       
   971 				formData.right = new FormAttachment(leftSash);
       
   972 			} catch (ClassCastException e1) {
       
   973 			}
       
   974 
       
   975 			this.parent.layout();
       
   976 
       
   977 			this.myGraph.repaint();
       
   978 
       
   979 		} else if (drawMode == Defines.FUNCTIONS_BINARIES_THREADS) {
       
   980 			// set the page's graph title
       
   981 			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
   982 			pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
       
   983 			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
       
   984 
       
   985 			// get rid of the thread table and its sash
       
   986 			if (this.myGraph.getRightSash() != null) {
       
   987 				this.myGraph.getRightSash().dispose();
       
   988 				this.myGraph.setRightSash(null);
       
   989 			}
       
   990 			if (   (this.myGraph.getThreadTable() != null)
       
   991 				&& (this.myGraph.getThreadTable().getTable() != null)) {
       
   992 				this.myGraph.getThreadTable().getTableViewer().getTable().dispose();
       
   993 				this.myGraph.getThreadTable().setTableViewer(null);
       
   994 			}
       
   995 
       
   996 			// get rid of the middle table's connection to the sash
       
   997 			try {
       
   998 				FormData formData = (FormData) this.myGraph.getBinaryTable().getTable().getLayoutData();
       
   999 				formData.right = new FormAttachment(100);
       
  1000 			} catch (ClassCastException e1) {
       
  1001 			}
       
  1002 
       
  1003 			// move the left sash to the middle
       
  1004 			try {
       
  1005 				FormData formData = (FormData) this.myGraph.getLeftSash().getLayoutData();
       
  1006 				formData.left = new FormAttachment(50); // middle
       
  1007 			} catch (ClassCastException e1) {
       
  1008 			}
       
  1009 
       
  1010 			// set the draw mode
       
  1011 			this.myGraph.setDrawMode(Defines.FUNCTIONS_BINARIES);
       
  1012 
       
  1013 			// show colors in the rightmost table
       
  1014 			this.myGraph.getBinaryTable().addColor(Defines.FUNCTIONS_BINARIES);
       
  1015 
       
  1016 			this.parent.layout();
       
  1017 
       
  1018 			this.myGraph.repaint();
       
  1019 		}
       
  1020 
       
  1021 		// this case should be drawMode == Defines.FUNCTIONS_BINARIES
       
  1022 		return;
       
  1023 	}
       
  1024 
       
  1025 	private void actionFunctionBinaryThread()
       
  1026 	{
       
  1027 		// current drawMode should be FUNCTIONS_BINARIES or FUNCTIONS_BINARIES_THREADS
       
  1028 		int drawMode = this.myGraph.getDrawMode();
       
  1029 		int graphIndex = this.myGraph.getGraphIndex();
       
  1030 
       
  1031 		if (drawMode != Defines.FUNCTIONS_BINARIES) {
       
  1032 			// this case should be drawMode == Defines.FUNCTIONS_BINARIES_THREADS
       
  1033 			return;
       
  1034 		}
       
  1035 
       
  1036 		setIsDrilldown(true);
       
  1037 
       
  1038 		// set the page's graph title
       
  1039 		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
  1040 		pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
       
  1041 		pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionToBinaryTo"));  //$NON-NLS-1$
       
  1042 
       
  1043 		// set the draw mode
       
  1044 		this.myGraph.setDrawMode(Defines.FUNCTIONS_BINARIES_THREADS);
       
  1045 
       
  1046 		// create the thread graph table viewer
       
  1047 		AddrThreadTable threadTable = this.myGraph.getThreadTable();
       
  1048 		threadTable.createTableViewer(Defines.FUNCTIONS_BINARIES_THREADS);
       
  1049 		threadTable.setIsDrilldown(true);
       
  1050 
       
  1051 		// create a reduced set of thread entries based on enabled binary and function entries
       
  1052 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
       
  1053 		Vector<ProfiledGeneric> threads = gppTrace.setFunctionBinaryThread(graphIndex);
       
  1054 		this.myGraph.setProfiledThreads(threads);
       
  1055 
       
  1056 		// put check marks on all rows, and sort by sample count
       
  1057 		threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
       
  1058 		threadTable.updateProfiledAndItemData(true);
       
  1059 		threadTable.getTableViewer().setAllChecked(true);
       
  1060 		threadTable.getTableViewer().refresh();
       
  1061 
       
  1062 		// remove colors where appropriate
       
  1063 		this.myGraph.getBinaryTable().removeColor(Defines.FUNCTIONS_BINARIES_THREADS);
       
  1064 
       
  1065 		// connect the 2nd and 3rd tables with a sash
       
  1066 		Sash rightSash   = new Sash(this.parent, SWT.VERTICAL);
       
  1067 
       
  1068 		final FormData rightSashData = new FormData();
       
  1069 		rightSashData.top    = new FormAttachment(0);
       
  1070 		rightSashData.bottom = new FormAttachment(100);
       
  1071 		rightSashData.left   = new FormAttachment(67); // two thirds
       
  1072 		rightSash.setLayoutData(rightSashData);
       
  1073 
       
  1074 		final Composite sashParent = this.parent;
       
  1075 		rightSash.addListener(SWT.Selection, new Listener() {
       
  1076 			public void handleEvent(Event event) {
       
  1077 				if (event.detail != SWT.DRAG) {
       
  1078 					rightSashData.left = new FormAttachment(0, event.x);
       
  1079 					sashParent.layout();
       
  1080 				}
       
  1081 			}
       
  1082 		});
       
  1083 
       
  1084 		myGraph.setRightSash(rightSash);
       
  1085 
       
  1086 		// attach the thread table to the sash
       
  1087 		final FormData viewerData = new FormData();
       
  1088 		viewerData.top    = new FormAttachment(0);
       
  1089 		viewerData.bottom = new FormAttachment(100);
       
  1090 		viewerData.left   = new FormAttachment(rightSash);
       
  1091 		viewerData.right  = new FormAttachment(100);
       
  1092 		threadTable.getTable().setLayoutData(viewerData);
       
  1093 
       
  1094 		// attach the binary table to the sash
       
  1095 		try {
       
  1096 			FormData formData = (FormData) this.myGraph.getBinaryTable().getTable().getLayoutData();
       
  1097 			formData.right = new FormAttachment(rightSash);
       
  1098 		} catch (ClassCastException e1) {
       
  1099 		}
       
  1100 
       
  1101 		// move the left sash to 1/3 from the left
       
  1102 		try {
       
  1103 			FormData formData = (FormData) this.myGraph.getLeftSash().getLayoutData();
       
  1104 			formData.left = new FormAttachment(33); // one third
       
  1105 		} catch (ClassCastException e1) {
       
  1106 		}
       
  1107 
       
  1108 		this.parent.layout();
       
  1109 
       
  1110 		this.myGraph.repaint();
       
  1111 	}
       
  1112 
       
  1113 	private void actionFunctionThread()
       
  1114 	{
       
  1115 		// current drawMode should be FUNCTIONS, FUNCTIONS_THREADS, or FUNCTIONS_THREADS_BINARIES
       
  1116 		int drawMode = this.myGraph.getDrawMode();
       
  1117 		int graphIndex = this.myGraph.getGraphIndex();
       
  1118 
       
  1119 		if (   drawMode != Defines.FUNCTIONS
       
  1120 			&& drawMode != Defines.FUNCTIONS_THREADS_BINARIES) {
       
  1121 			return;
       
  1122 		}
       
  1123 
       
  1124 		setIsDrilldown(true);
       
  1125 
       
  1126 		if (drawMode == Defines.FUNCTIONS) {
       
  1127 			// set the page's graph title
       
  1128 			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
  1129 			pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
       
  1130 			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
       
  1131 
       
  1132 			// set the draw mode
       
  1133 			this.myGraph.setDrawMode(Defines.FUNCTIONS_THREADS);
       
  1134 
       
  1135 			// create the thread graph table viewer
       
  1136 			AddrThreadTable threadTable = this.myGraph.getThreadTable();
       
  1137 			threadTable.createTableViewer(Defines.FUNCTIONS_THREADS);
       
  1138 			threadTable.setIsDrilldown(true);
       
  1139 
       
  1140 			// create a reduced set of thread entries based on enabled function entries
       
  1141 			GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
       
  1142 			Vector<ProfiledGeneric> threads = gppTrace.setFunctionThread(graphIndex);
       
  1143 			this.myGraph.setProfiledThreads(threads);
       
  1144 
       
  1145 			// put check marks on all rows, and sort by sample count
       
  1146 			threadTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledThreads());
       
  1147 			threadTable.updateProfiledAndItemData(true);
       
  1148 			threadTable.getTableViewer().setAllChecked(true);
       
  1149 			threadTable.getTableViewer().refresh();
       
  1150 
       
  1151 			// remove colors where appropriate
       
  1152 			removeColor(Defines.FUNCTIONS_THREADS);
       
  1153 
       
  1154 			// connect the tables with a sash
       
  1155 			Sash leftSash   = new Sash(this.parent, SWT.VERTICAL);
       
  1156 
       
  1157 			final FormData leftSashData = new FormData();
       
  1158 			leftSashData.top    = new FormAttachment(0);
       
  1159 			leftSashData.bottom = new FormAttachment(100);
       
  1160 			leftSashData.left   = new FormAttachment(50); // middle
       
  1161 			leftSash.setLayoutData(leftSashData);
       
  1162 
       
  1163 			final Composite sashParent = this.parent;
       
  1164 			leftSash.addListener(SWT.Selection, new Listener() {
       
  1165 				public void handleEvent(Event event) {
       
  1166 					if (event.detail != SWT.DRAG) {
       
  1167 						leftSashData.left = new FormAttachment(0, event.x);
       
  1168 						sashParent.layout();
       
  1169 					}
       
  1170 				}
       
  1171 			});
       
  1172 
       
  1173 			myGraph.setLeftSash(leftSash);
       
  1174 
       
  1175 			// attach the thread table to the sash
       
  1176 			final FormData viewerData = new FormData();
       
  1177 			viewerData.top    = new FormAttachment(0);
       
  1178 			viewerData.bottom = new FormAttachment(100);
       
  1179 			viewerData.left   = new FormAttachment(leftSash);
       
  1180 			viewerData.right  = new FormAttachment(100);
       
  1181 			threadTable.getTable().setLayoutData(viewerData);
       
  1182 
       
  1183 			// attach the function table to the sash
       
  1184 			try {
       
  1185 				FormData formData = (FormData) this.table.getLayoutData();
       
  1186 				formData.right = new FormAttachment(leftSash);
       
  1187 			} catch (ClassCastException e1) {
       
  1188 			}
       
  1189 
       
  1190 			this.parent.layout();
       
  1191 
       
  1192 			this.myGraph.repaint();
       
  1193 
       
  1194 		} else if (drawMode == Defines.FUNCTIONS_THREADS_BINARIES) {
       
  1195 			// set the page's graph title
       
  1196 			ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
  1197 			pV.getTitle().setText(Messages.getString("AddrFunctionTable.threadLoad"));  //$NON-NLS-1$
       
  1198 			pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionTo"));  //$NON-NLS-1$
       
  1199 
       
  1200 			// get rid of the binary table and its sash
       
  1201 			if (this.myGraph.getRightSash() != null) {
       
  1202 				this.myGraph.getRightSash().dispose();
       
  1203 				this.myGraph.setRightSash(null);
       
  1204 			}
       
  1205 			if (   (this.myGraph.getBinaryTable() != null)
       
  1206 				&& (this.myGraph.getBinaryTable().getTable() != null)) {
       
  1207 				this.myGraph.getBinaryTable().getTableViewer().getTable().dispose();
       
  1208 				this.myGraph.getBinaryTable().setTableViewer(null);
       
  1209 			}
       
  1210 
       
  1211 			// get rid of the middle table's connection to the sash
       
  1212 			try {
       
  1213 				FormData formData = (FormData) this.myGraph.getThreadTable().getTable().getLayoutData();
       
  1214 				formData.right = new FormAttachment(100);
       
  1215 			} catch (ClassCastException e1) {
       
  1216 			}
       
  1217 
       
  1218 			// move the left sash to the middle
       
  1219 			try {
       
  1220 				FormData formData = (FormData) this.myGraph.getLeftSash().getLayoutData();
       
  1221 				formData.left = new FormAttachment(50); // middle
       
  1222 			} catch (ClassCastException e1) {
       
  1223 			}
       
  1224 
       
  1225 			// set the draw mode
       
  1226 			this.myGraph.setDrawMode(Defines.FUNCTIONS_THREADS);
       
  1227 
       
  1228 			// show colors in the rightmost table
       
  1229 			this.myGraph.getThreadTable().addColor(Defines.FUNCTIONS_THREADS);
       
  1230 
       
  1231 			this.parent.layout();
       
  1232 
       
  1233 			this.myGraph.repaint();
       
  1234 		}
       
  1235 
       
  1236 		// this case should be drawMode == Defines.FUNCTIONS_THREADS
       
  1237 		return;
       
  1238 	}
       
  1239 
       
  1240 	private void actionFunctionThreadBinary()
       
  1241 	{
       
  1242 		// current drawMode is FUNCTIONS_THREADS, or FUNCTIONS_THREADS_BINARIES
       
  1243 		int drawMode = this.myGraph.getDrawMode();
       
  1244 		int graphIndex = this.myGraph.getGraphIndex();
       
  1245 
       
  1246 		if (drawMode != Defines.FUNCTIONS_THREADS) {
       
  1247 			// this case should be drawMode == Defines.FUNCTIONS_THREADS_BINARIES
       
  1248 			return;
       
  1249 		}
       
  1250 
       
  1251 		setIsDrilldown(true);
       
  1252 
       
  1253 		// set the page's graph title
       
  1254 		ProfileVisualiser pV =  NpiInstanceRepository.getInstance().getProfilePage(this.myGraph.getUid(), this.myGraph.getGraphIndex());
       
  1255 		pV.getTitle().setText(Messages.getString("AddrFunctionTable.binaryLoad"));  //$NON-NLS-1$
       
  1256 		pV.getTitle2().setText(Messages.getString("AddrFunctionTable.functionToThreadTo"));  //$NON-NLS-1$
       
  1257 
       
  1258 		// set the draw mode
       
  1259 		this.myGraph.setDrawMode(Defines.FUNCTIONS_THREADS_BINARIES);
       
  1260 
       
  1261 		// create the binary graph table viewer
       
  1262 		AddrBinaryTable binaryTable = this.myGraph.getBinaryTable();
       
  1263 		binaryTable.createTableViewer(Defines.FUNCTIONS_THREADS_BINARIES);
       
  1264 		binaryTable.setIsDrilldown(true);
       
  1265 
       
  1266 		// create a reduced set of binary entries based on enabled thread entries
       
  1267 		GppTrace gppTrace = (GppTrace) this.myGraph.getTrace();
       
  1268 		Vector<ProfiledGeneric> binaries = gppTrace.setFunctionThreadBinary(graphIndex);
       
  1269 		this.myGraph.setProfiledBinaries(binaries);
       
  1270 
       
  1271 		// put check marks on all rows, and sort by sample count
       
  1272 		binaryTable.quickSort(COLUMN_ID_SAMPLE_COUNT, this.myGraph.getProfiledBinaries());
       
  1273 		binaryTable.updateProfiledAndItemData(true);
       
  1274 		binaryTable.getTableViewer().setAllChecked(true);
       
  1275 		binaryTable.getTableViewer().refresh();
       
  1276 
       
  1277 		// remove colors where appropriate
       
  1278 		this.myGraph.getThreadTable().removeColor(Defines.FUNCTIONS_THREADS_BINARIES);
       
  1279 
       
  1280 		// connect the 2nd and 3rd tables with a sash
       
  1281 		Sash rightSash   = new Sash(this.parent, SWT.VERTICAL);
       
  1282 
       
  1283 		final FormData rightSashData = new FormData();
       
  1284 		rightSashData.top    = new FormAttachment(0);
       
  1285 		rightSashData.bottom = new FormAttachment(100);
       
  1286 		rightSashData.left   = new FormAttachment(67); // two thirds
       
  1287 		rightSash.setLayoutData(rightSashData);
       
  1288 
       
  1289 		final Composite sashParent = this.parent;
       
  1290 		rightSash.addListener(SWT.Selection, new Listener() {
       
  1291 			public void handleEvent(Event event) {
       
  1292 				if (event.detail != SWT.DRAG) {
       
  1293 					rightSashData.left = new FormAttachment(0, event.x);
       
  1294 					sashParent.layout();
       
  1295 				}
       
  1296 			}
       
  1297 		});
       
  1298 
       
  1299 		myGraph.setRightSash(rightSash);
       
  1300 
       
  1301 		// attach the binary table to the sash
       
  1302 		final FormData viewerData = new FormData();
       
  1303 		viewerData.top    = new FormAttachment(0);
       
  1304 		viewerData.bottom = new FormAttachment(100);
       
  1305 		viewerData.left   = new FormAttachment(rightSash);
       
  1306 		viewerData.right  = new FormAttachment(100);
       
  1307 		binaryTable.getTable().setLayoutData(viewerData);
       
  1308 
       
  1309 		// attach the thread table to the sash
       
  1310 		try {
       
  1311 			FormData formData = (FormData) this.myGraph.getThreadTable().getTable().getLayoutData();
       
  1312 			formData.right = new FormAttachment(rightSash);
       
  1313 		} catch (ClassCastException e1) {
       
  1314 		}
       
  1315 
       
  1316 		// move the left sash to 1/3 from the left
       
  1317 		try {
       
  1318 			FormData formData = (FormData) this.myGraph.getLeftSash().getLayoutData();
       
  1319 			formData.left = new FormAttachment(33); // one third
       
  1320 		} catch (ClassCastException e1) {
       
  1321 		}
       
  1322 
       
  1323 		this.parent.layout();
       
  1324 
       
  1325 		this.myGraph.repaint();
       
  1326 	}
       
  1327 	
       
  1328 	private void actionSourceLookup() {
       
  1329 		// source look up for selected items
       
  1330 		TableItem selectedItem = table.getSelection()[0];
       
  1331 		if (selectedItem.getData() instanceof ProfiledGeneric)
       
  1332 		{
       
  1333 			ProfiledGeneric pGeneric = (ProfiledGeneric)selectedItem.getData();
       
  1334 			
       
  1335 			if (pGeneric instanceof ProfiledFunction) {
       
  1336 				ProfiledFunction pFunc = (ProfiledFunction) pGeneric;
       
  1337 				SourceLookup.getInstance().lookupAndopenEditorWithHighlight (pFunc.getNameString(), pFunc.getFunctionBinaryName());
       
  1338 			}
       
  1339 		}
       
  1340 	}
       
  1341 
       
  1342 	public void focusGained(FocusEvent e) {}
       
  1343 
       
  1344 	public void focusLost(FocusEvent e) {}
       
  1345 
       
  1346 	public void piEventReceived(PIEvent be)
       
  1347 	{
       
  1348 		if (be.getType() == PIEvent.SELECTION_AREA_CHANGED3)
       
  1349 		{
       
  1350 			// % loads, % load strings, and/or sample counts have been updated
       
  1351 			// due to a change in the graph area selected, and all table items
       
  1352 			// need to be checked
       
  1353 			updateProfiledAndItemData(true);
       
  1354 
       
  1355 			Display.getDefault().syncExec(new Runnable() {
       
  1356 				public void run() {
       
  1357 					quickSort(sortColumn, profiledFunctions);
       
  1358 
       
  1359 					// initially, all rows are selected
       
  1360 					tableViewer.setAllChecked(true);
       
  1361 
       
  1362 					table.redraw();
       
  1363 				}
       
  1364 			});
       
  1365 		}
       
  1366 		else if (   (be.getType() == PIEvent.SELECTION_AREA_CHANGED2)
       
  1367 				 || (be.getType() == PIEvent.CHANGED_FUNCTION_TABLE))
       
  1368 		{
       
  1369 			int graphIndex = this.myGraph.getGraphIndex();
       
  1370 
       
  1371 			// This routine does not change which functions are enabled, but it enables
       
  1372 			// all entries in the 2nd and 3rd tables.
       
  1373 			// It assumes that GppTrace.setSelectedArea(), action("add") or action("remove") has set
       
  1374 			// the % load and sample counts for functions, except for the threshold list.
       
  1375 			if (be.getType() == PIEvent.SELECTION_AREA_CHANGED2) {
       
  1376 				int thresholdCount = (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountFunction"); //$NON-NLS-1$
       
  1377 				if (thresholdCount > 0) {
       
  1378 					Vector<ProfiledGeneric> pGeneric = this.myGraph.getProfiledFunctions();
       
  1379 					int sampleCount = 0;
       
  1380 					for (int i = 0; i < pGeneric.size(); i++)
       
  1381 						if (pGeneric.elementAt(i).getTotalSampleCount() < thresholdCount)
       
  1382 							sampleCount += pGeneric.elementAt(i).getSampleCount(graphIndex);
       
  1383 					this.myGraph.getThresholdFunction().setSampleCount(graphIndex, sampleCount);
       
  1384 				}
       
  1385 			}
       
  1386 
       
  1387 			// redraw this table
       
  1388 			Display.getDefault().syncExec(new Runnable() {
       
  1389 				public void run() {
       
  1390 					if (   (sortColumn == COLUMN_ID_PERCENT_LOAD)
       
  1391 						|| (sortColumn == COLUMN_ID_SAMPLE_COUNT))
       
  1392 					{
       
  1393 						quickSort(sortColumn, profiledFunctions);
       
  1394 					}
       
  1395 					else
       
  1396 						refreshTableViewer();
       
  1397 
       
  1398 					table.redraw();
       
  1399 				}
       
  1400 			});
       
  1401 
       
  1402 			int drawMode = this.myGraph.getDrawMode();
       
  1403 			if (drawMode == Defines.FUNCTIONS)
       
  1404 				return;
       
  1405 
       
  1406 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
       
  1407 			Vector<ProfiledGeneric> traceFunctions = trace.getIndexedFunctions();
       
  1408 
       
  1409 			int startSampleIndex = trace.getStartSampleIndex();
       
  1410 			int endSampleIndex   = trace.getEndSampleIndex();
       
  1411 			double percentPerSample;
       
  1412 			if (startSampleIndex == endSampleIndex)
       
  1413 				percentPerSample = 0.0;
       
  1414 			else
       
  1415 				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
       
  1416 
       
  1417 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
       
  1418 
       
  1419 			switch (drawMode) {
       
  1420 				case Defines.FUNCTIONS_THREADS:
       
  1421 				{
       
  1422 					// get new thread counts and loads
       
  1423 					Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
       
  1424 					Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
       
  1425 					Hashtable<String,String> foundThreads = new Hashtable<String,String>();
       
  1426 
       
  1427 					// previous threads are not necessarily graphed this time
       
  1428 					Enumeration<ProfiledGeneric> enu = graphThreads.elements();
       
  1429 					while (enu.hasMoreElements()) {
       
  1430 						ProfiledThread pThread = (ProfiledThread) enu.nextElement();
       
  1431 						pThread.setEnabled(graphIndex, false);
       
  1432 					}
       
  1433 					graphThreads.clear();
       
  1434 
       
  1435 					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
       
  1436 					if (thresholdThread.isEnabled(graphIndex)) {
       
  1437 						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
       
  1438 						// disable all items below the threshold
       
  1439 						for (int i = 0; i < items.size(); i++) {
       
  1440 							items.get(i).setEnabled(graphIndex, false);
       
  1441 						}
       
  1442 					}
       
  1443 
       
  1444 					GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1445 
       
  1446 					// set up in case we find threads below the threshold
       
  1447 					boolean lowThread;
       
  1448 					thresholdThread.init(graphIndex);
       
  1449 
       
  1450 					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
       
  1451 					for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1452 						GppSample sample = sortedSamples[i];
       
  1453 
       
  1454 						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
       
  1455 						if (pFunction.isEnabled(graphIndex)) {
       
  1456 							// thread list is based on functions
       
  1457 							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
       
  1458 							String threadName = pThread.getNameString();
       
  1459 
       
  1460 							lowThread = pThread.getTotalSampleCount() < threadThreshold;
       
  1461 
       
  1462 							if (!foundThreads.containsKey(threadName)) {
       
  1463 								foundThreads.put(threadName, threadName);
       
  1464 								if (lowThread) {
       
  1465 									thresholdThread.addItem(graphIndex, pThread, 1);
       
  1466 								} else {
       
  1467 									pThread.setEnabled(graphIndex, true);
       
  1468 									pThread.setSampleCount(graphIndex, 1);
       
  1469 									graphThreads.add(pThread);
       
  1470 								}
       
  1471 							} else {
       
  1472 								if (lowThread)
       
  1473 									thresholdThread.incSampleCount(graphIndex);
       
  1474 								else
       
  1475 									pThread.incSampleCount(graphIndex);
       
  1476 							}
       
  1477 						}
       
  1478 					}
       
  1479 
       
  1480 					// set the % load
       
  1481 					for (int i = 0; i < graphThreads.size(); i++) {
       
  1482 						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
       
  1483 						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
       
  1484 					}
       
  1485 					thresholdThread.setLoadAndString(graphIndex,
       
  1486 							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
       
  1487 
       
  1488 					// update the table items and redraw the table
       
  1489 					this.myGraph.getThreadTable().piEventReceived(be3);
       
  1490 					break;
       
  1491 				}
       
  1492 				case Defines.FUNCTIONS_THREADS_BINARIES:
       
  1493 				{
       
  1494 					// get new thread and binary counts and loads
       
  1495 					Vector<ProfiledGeneric> traceThreads   = trace.getIndexedThreads();
       
  1496 					Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
       
  1497 					Vector<ProfiledGeneric> graphThreads   = this.myGraph.getProfiledThreads();
       
  1498 					Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
       
  1499 					Hashtable<String,String> foundThreads  = new Hashtable<String,String>();
       
  1500 					Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
       
  1501 
       
  1502 					// previous binaries are not necessarily graphed this time
       
  1503 					Enumeration<ProfiledGeneric> enuBinary = graphBinaries.elements();
       
  1504 					while (enuBinary.hasMoreElements()) {
       
  1505 						ProfiledBinary pBinary = (ProfiledBinary) enuBinary.nextElement();
       
  1506 						pBinary.setEnabled(graphIndex, false);
       
  1507 					}
       
  1508 					graphBinaries.clear();
       
  1509 
       
  1510 					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
       
  1511 
       
  1512 					if (thresholdBinary.isEnabled(graphIndex)) {
       
  1513 						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
       
  1514 						// disable all items below the threshold
       
  1515 						for (int i = 0; i < items.size(); i++) {
       
  1516 							items.get(i).setEnabled(graphIndex, false);
       
  1517 						}
       
  1518 					}
       
  1519 
       
  1520 					// previous threads are not necessarily graphed this time
       
  1521 					Enumeration<ProfiledGeneric> enuThread = graphThreads.elements();
       
  1522 					while (enuThread.hasMoreElements()) {
       
  1523 						ProfiledThread pThread = (ProfiledThread) enuThread.nextElement();
       
  1524 						pThread.setEnabled(graphIndex, false);
       
  1525 					}
       
  1526 					graphThreads.clear();
       
  1527 
       
  1528 					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
       
  1529 
       
  1530 					if (thresholdThread.isEnabled(graphIndex)) {
       
  1531 						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
       
  1532 						// disable all items below the threshold
       
  1533 						for (int i = 0; i < items.size(); i++) {
       
  1534 							items.get(i).setEnabled(graphIndex, false);
       
  1535 						}
       
  1536 					}
       
  1537 
       
  1538 					GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1539 
       
  1540 					// set up in case we find binaries below the threshold
       
  1541 					boolean lowBinary;
       
  1542 					thresholdBinary.init(graphIndex);
       
  1543 
       
  1544 					// set up in case we find threads below the threshold
       
  1545 					boolean lowThread;
       
  1546 					thresholdThread.init(graphIndex);
       
  1547 
       
  1548 					int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
       
  1549 					for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1550 						GppSample sample = sortedSamples[i];
       
  1551 
       
  1552 						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
       
  1553 						if (pFunction.isEnabled(graphIndex)) {
       
  1554 							// thread list is based on functions
       
  1555 							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
       
  1556 							String threadName = pThread.getNameString();
       
  1557 
       
  1558 							lowThread = pThread.getTotalSampleCount() < threadThreshold;
       
  1559 
       
  1560 							if (!foundThreads.containsKey(threadName)) {
       
  1561 								foundThreads.put(threadName, threadName);
       
  1562 								if (lowThread) {
       
  1563 									thresholdThread.addItem(graphIndex, pThread, 1);
       
  1564 								} else {
       
  1565 									pThread.setEnabled(graphIndex, true);
       
  1566 									pThread.setSampleCount(graphIndex, 1);
       
  1567 									graphThreads.add(pThread);
       
  1568 								}
       
  1569 							} else {
       
  1570 								if (lowThread)
       
  1571 									thresholdThread.incSampleCount(graphIndex);
       
  1572 								else
       
  1573 									pThread.incSampleCount(graphIndex);
       
  1574 							}
       
  1575 
       
  1576 							// binary list is based on functions and threads
       
  1577 							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
       
  1578 							String binaryName = pBinary.getNameString();
       
  1579 
       
  1580 							lowBinary = pBinary.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
       
  1581 
       
  1582 							if (!foundBinaries.containsKey(binaryName)) {
       
  1583 								foundBinaries.put(binaryName, binaryName);
       
  1584 								if (lowBinary) {
       
  1585 									thresholdBinary.addItem(graphIndex, pBinary, 1);
       
  1586 								} else {
       
  1587 									pBinary.setEnabled(graphIndex, true);
       
  1588 									pBinary.setSampleCount(graphIndex, 1);
       
  1589 									graphBinaries.add(pBinary);
       
  1590 								}
       
  1591 							} else {
       
  1592 								if (lowBinary)
       
  1593 									thresholdBinary.incSampleCount(graphIndex);
       
  1594 								else
       
  1595 									pBinary.incSampleCount(graphIndex);
       
  1596 							}
       
  1597 						}
       
  1598 					}
       
  1599 
       
  1600 					// set the % load
       
  1601 					for (int i = 0; i < graphThreads.size(); i++) {
       
  1602 						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
       
  1603 						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
       
  1604 					}
       
  1605 					thresholdThread.setLoadAndString(graphIndex,
       
  1606 							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
       
  1607 
       
  1608 					for (int i = 0; i < graphBinaries.size(); i++) {
       
  1609 						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
       
  1610 						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1611 					}
       
  1612 					thresholdBinary.setLoadAndString(graphIndex,
       
  1613 							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1614 
       
  1615 					// update the table items and redraw the table
       
  1616 					this.myGraph.getThreadTable().piEventReceived(be3);
       
  1617 					this.myGraph.getBinaryTable().piEventReceived(be3);
       
  1618 					break;
       
  1619 				}
       
  1620 				case Defines.FUNCTIONS_BINARIES:
       
  1621 				{
       
  1622 					// get new counts and loads
       
  1623 					Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
       
  1624 					Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
       
  1625 					Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
       
  1626 
       
  1627 					// previous binaries are not necessarily graphed this time
       
  1628 					Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
       
  1629 					while (enu.hasMoreElements()) {
       
  1630 						ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
       
  1631 						pBinary.setEnabled(graphIndex, false);
       
  1632 					}
       
  1633 					graphBinaries.clear();
       
  1634 
       
  1635 					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
       
  1636 
       
  1637 					if (thresholdBinary.isEnabled(graphIndex)) {
       
  1638 						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
       
  1639 						// disable all items below the threshold
       
  1640 						for (int i = 0; i < items.size(); i++) {
       
  1641 							items.get(i).setEnabled(graphIndex, false);
       
  1642 						}
       
  1643 					}
       
  1644 
       
  1645 					GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1646 
       
  1647 					// set up in case we find binaries below the threshold
       
  1648 					boolean lowBinary;
       
  1649 					thresholdBinary.init(graphIndex);
       
  1650 
       
  1651 					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
       
  1652 					for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1653 						GppSample sample = sortedSamples[i];
       
  1654 
       
  1655 						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
       
  1656 						if (pFunction.isEnabled(graphIndex)) {
       
  1657 							// binary list is based on functions
       
  1658 							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
       
  1659 							String binaryName = pBinary.getNameString();
       
  1660 
       
  1661 							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
       
  1662 
       
  1663 							if (!foundBinaries.containsKey(binaryName)) {
       
  1664 								foundBinaries.put(binaryName, binaryName);
       
  1665 								if (lowBinary) {
       
  1666 									thresholdBinary.addItem(graphIndex, pBinary, 1);
       
  1667 								} else {
       
  1668 									pBinary.setEnabled(graphIndex, true);
       
  1669 									pBinary.setSampleCount(graphIndex, 1);
       
  1670 									graphBinaries.add(pBinary);
       
  1671 								}
       
  1672 							} else {
       
  1673 								if (lowBinary)
       
  1674 									thresholdBinary.incSampleCount(graphIndex);
       
  1675 								else
       
  1676 									pBinary.incSampleCount(graphIndex);
       
  1677 							}
       
  1678 						}
       
  1679 					}
       
  1680 
       
  1681 					// set the % load
       
  1682 					for (int i = 0; i < graphBinaries.size(); i++) {
       
  1683 						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
       
  1684 						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1685 					}
       
  1686 					thresholdBinary.setLoadAndString(graphIndex,
       
  1687 							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1688 
       
  1689 					// update the table items and redraw the table
       
  1690 					this.myGraph.getBinaryTable().piEventReceived(be3);
       
  1691 					break;
       
  1692 				}
       
  1693 				case Defines.FUNCTIONS_BINARIES_THREADS:
       
  1694 				{
       
  1695 					// get new binary and thread counts and loads
       
  1696 					Vector<ProfiledGeneric> traceThreads    = trace.getIndexedThreads();
       
  1697 					Vector<ProfiledGeneric> traceBinaries   = trace.getIndexedBinaries();
       
  1698 					Vector<ProfiledGeneric> graphThreads    = this.myGraph.getProfiledThreads();
       
  1699 					Vector<ProfiledGeneric> graphBinaries   = this.myGraph.getProfiledBinaries();
       
  1700 					Hashtable<String,String> foundThreads   = new Hashtable<String,String>();
       
  1701 					Hashtable<String,String> foundBinaries  = new Hashtable<String,String>();
       
  1702 
       
  1703 					// previous threads are not necessarily graphed this time
       
  1704 					Enumeration<ProfiledGeneric> enuThreads = graphThreads.elements();
       
  1705 					while (enuThreads.hasMoreElements()) {
       
  1706 						ProfiledThread pThread = (ProfiledThread) enuThreads.nextElement();
       
  1707 						pThread.setEnabled(graphIndex, false);
       
  1708 					}
       
  1709 					graphThreads.clear();
       
  1710 
       
  1711 					ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
       
  1712 
       
  1713 					if (thresholdThread.isEnabled(graphIndex)) {
       
  1714 						ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
       
  1715 						// disable all items below the threshold
       
  1716 						for (int i = 0; i < items.size(); i++) {
       
  1717 							items.get(i).setEnabled(graphIndex, false);
       
  1718 						}
       
  1719 					}
       
  1720 
       
  1721 					// previous binaries are not necessarily graphed this time
       
  1722 					Enumeration<ProfiledGeneric> enuBinary = graphBinaries.elements();
       
  1723 					while (enuBinary.hasMoreElements()) {
       
  1724 						ProfiledBinary pBinary = (ProfiledBinary) enuBinary.nextElement();
       
  1725 						pBinary.setEnabled(graphIndex, false);
       
  1726 					}
       
  1727 					graphBinaries.clear();
       
  1728 
       
  1729 					ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
       
  1730 
       
  1731 					if (thresholdBinary.isEnabled(graphIndex)) {
       
  1732 						ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
       
  1733 						// disable all items below the threshold
       
  1734 						for (int i = 0; i < items.size(); i++) {
       
  1735 							items.get(i).setEnabled(graphIndex, false);
       
  1736 						}
       
  1737 					}
       
  1738 
       
  1739 					GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1740 
       
  1741 					// set up in case we find threads below the threshold
       
  1742 					boolean lowThread;
       
  1743 					thresholdThread.init(graphIndex);
       
  1744 
       
  1745 					// set up in case we find binaries below the threshold
       
  1746 					boolean lowBinary;
       
  1747 					thresholdBinary.init(graphIndex);
       
  1748 
       
  1749 					int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
       
  1750 					for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1751 						GppSample sample = sortedSamples[i];
       
  1752 
       
  1753 						ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex);
       
  1754 						if (pFunction.isEnabled(graphIndex)) {
       
  1755 							// binary list is based on
       
  1756 							ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
       
  1757 							String binaryName = pBinary.getNameString();
       
  1758 
       
  1759 							lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
       
  1760 
       
  1761 							if (!foundBinaries.containsKey(binaryName)) {
       
  1762 								foundBinaries.put(binaryName, binaryName);
       
  1763 								if (lowBinary) {
       
  1764 									thresholdBinary.addItem(graphIndex, pBinary, 1);
       
  1765 								} else {
       
  1766 									pBinary.setEnabled(graphIndex, true);
       
  1767 									pBinary.setSampleCount(graphIndex, 1);
       
  1768 									graphBinaries.add(pBinary);
       
  1769 								}
       
  1770 							} else {
       
  1771 								if (lowBinary)
       
  1772 									thresholdBinary.incSampleCount(graphIndex);
       
  1773 								else
       
  1774 									pBinary.incSampleCount(graphIndex);
       
  1775 							}
       
  1776 
       
  1777 							// thread list is based on functions and binaries
       
  1778 							ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
       
  1779 							String threadName = pThread.getNameString();
       
  1780 
       
  1781 							lowThread = pThread.getTotalSampleCount() < (Integer)NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
       
  1782 
       
  1783 							if (!foundThreads.containsKey(threadName)) {
       
  1784 								foundThreads.put(threadName, threadName);
       
  1785 								if (lowThread) {
       
  1786 									thresholdThread.addItem(graphIndex, pThread, 1);
       
  1787 								} else {
       
  1788 									pThread.setEnabled(graphIndex, true);
       
  1789 									pThread.setSampleCount(graphIndex, 1);
       
  1790 									graphThreads.add(pThread);
       
  1791 								}
       
  1792 							} else {
       
  1793 								if (lowThread)
       
  1794 									thresholdThread.incSampleCount(graphIndex);
       
  1795 								else
       
  1796 									pThread.incSampleCount(graphIndex);
       
  1797 							}
       
  1798 						}
       
  1799 					}
       
  1800 
       
  1801 					// set the % load
       
  1802 					for (int i = 0; i < graphThreads.size(); i++) {
       
  1803 						ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
       
  1804 						pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
       
  1805 					}
       
  1806 					thresholdThread.setLoadAndString(graphIndex,
       
  1807 							(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
       
  1808 
       
  1809 					for (int i = 0; i < graphBinaries.size(); i++) {
       
  1810 						ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
       
  1811 						pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1812 					}
       
  1813 					thresholdBinary.setLoadAndString(graphIndex,
       
  1814 							(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1815 
       
  1816 					// update the table items and redraw the table
       
  1817 					this.myGraph.getThreadTable().piEventReceived(be3);
       
  1818 					this.myGraph.getBinaryTable().piEventReceived(be3);
       
  1819 					break;
       
  1820 				}
       
  1821 				default:
       
  1822 				{
       
  1823 					break;
       
  1824 				}
       
  1825 			}
       
  1826 		}
       
  1827 		else if (be.getType() == PIEvent.CHANGED_THREAD_TABLE)
       
  1828 		{
       
  1829 			// This routine enables all entries in the next table
       
  1830 
       
  1831 			int drawMode = this.myGraph.getDrawMode();
       
  1832 			if (drawMode != Defines.FUNCTIONS_THREADS_BINARIES)
       
  1833 				return;
       
  1834 
       
  1835 			// we don't need to redraw the function table, since it has not changed
       
  1836 
       
  1837 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
       
  1838 			Vector<ProfiledGeneric> traceThreads = trace.getIndexedThreads();
       
  1839 
       
  1840 			int graphIndex = this.myGraph.getGraphIndex();
       
  1841 			int startSampleIndex = trace.getStartSampleIndex();
       
  1842 			int endSampleIndex   = trace.getEndSampleIndex();
       
  1843 			double percentPerSample;
       
  1844 			if (startSampleIndex == endSampleIndex)
       
  1845 				percentPerSample = 0.0;
       
  1846 			else
       
  1847 				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
       
  1848 
       
  1849 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
       
  1850 
       
  1851 			// get new binary counts and loads
       
  1852 			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
       
  1853 			Vector<ProfiledGeneric> graphBinaries  = this.myGraph.getProfiledBinaries();
       
  1854 			Hashtable<String,String> foundBinaries = new Hashtable<String,String>();
       
  1855 
       
  1856 			// previous binaries are not necessarily graphed this time
       
  1857 			Enumeration<ProfiledGeneric> enu = graphBinaries.elements();
       
  1858 			while (enu.hasMoreElements()) {
       
  1859 				ProfiledBinary pBinary = (ProfiledBinary) enu.nextElement();
       
  1860 				pBinary.setEnabled(graphIndex, false);
       
  1861 			}
       
  1862 			graphBinaries.clear();
       
  1863 
       
  1864 			ProfiledThreshold thresholdBinary = this.myGraph.getThresholdBinary();
       
  1865 
       
  1866 			if (thresholdBinary.isEnabled(graphIndex)) {
       
  1867 				ArrayList<ProfiledGeneric> items = thresholdBinary.getItems(graphIndex);
       
  1868 				// disable all items below the threshold
       
  1869 				for (int i = 0; i < items.size(); i++) {
       
  1870 					items.get(i).setEnabled(graphIndex, false);
       
  1871 				}
       
  1872 			}
       
  1873 
       
  1874 			GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1875 
       
  1876 			// set up in case we find binaries below the threshold
       
  1877 			boolean lowBinary;
       
  1878 			thresholdBinary.init(graphIndex);
       
  1879 			
       
  1880 			int binaryThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountBinary"); //$NON-NLS-1$
       
  1881 			for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1882 				GppSample sample = sortedSamples[i];
       
  1883 
       
  1884 				ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
       
  1885 				if (pThread.isEnabled(graphIndex)) {
       
  1886 					// binary list is based on threads
       
  1887 					ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
       
  1888 					String binaryName = pBinary.getNameString();
       
  1889 
       
  1890 					lowBinary = pBinary.getTotalSampleCount() < binaryThreshold;
       
  1891 
       
  1892 					if (!foundBinaries.containsKey(binaryName)) {
       
  1893 						foundBinaries.put(binaryName, binaryName);
       
  1894 						if (lowBinary) {
       
  1895 							thresholdBinary.addItem(graphIndex, pBinary, 1);
       
  1896 						} else {
       
  1897 							pBinary.setEnabled(graphIndex, true);
       
  1898 							pBinary.setSampleCount(graphIndex, 1);
       
  1899 							graphBinaries.add(pBinary);
       
  1900 						}
       
  1901 					} else {
       
  1902 						if (lowBinary)
       
  1903 							thresholdBinary.incSampleCount(graphIndex);
       
  1904 						else
       
  1905 							pBinary.incSampleCount(graphIndex);
       
  1906 					}
       
  1907 				}
       
  1908 			}
       
  1909 
       
  1910 			// set the % load
       
  1911 			for (int i = 0; i < graphBinaries.size(); i++) {
       
  1912 				ProfiledBinary pBinary = (ProfiledBinary) graphBinaries.elementAt(i);
       
  1913 				pBinary.setLoadAndString(graphIndex, (float)(pBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1914 			}
       
  1915 			thresholdBinary.setLoadAndString(graphIndex,
       
  1916 					(float)(thresholdBinary.getSampleCount(graphIndex)*percentPerSample));
       
  1917 
       
  1918 			// update the table items and redraw the table
       
  1919 			this.myGraph.getBinaryTable().piEventReceived(be3);
       
  1920 		}
       
  1921 		else if (be.getType() == PIEvent.CHANGED_BINARY_TABLE)
       
  1922 		{
       
  1923 			// This routine enables all entries in the next table
       
  1924 
       
  1925 			int drawMode = this.myGraph.getDrawMode();
       
  1926 			if (drawMode != Defines.FUNCTIONS_BINARIES_THREADS)
       
  1927 				return;
       
  1928 
       
  1929 			// we don't need to redraw the function table, since it has not changed
       
  1930 
       
  1931 			GppTrace trace = (GppTrace)(this.myGraph.getTrace());
       
  1932 			Vector<ProfiledGeneric> traceBinaries  = trace.getIndexedBinaries();
       
  1933 
       
  1934 			int graphIndex = this.myGraph.getGraphIndex();
       
  1935 			int startSampleIndex = trace.getStartSampleIndex();
       
  1936 			int endSampleIndex   = trace.getEndSampleIndex();
       
  1937 			double percentPerSample;
       
  1938 			if (startSampleIndex == endSampleIndex)
       
  1939 				percentPerSample = 0.0;
       
  1940 			else
       
  1941 				percentPerSample = 100.0 / ((double)(endSampleIndex - startSampleIndex));
       
  1942 
       
  1943 			PIEvent be3 = new PIEvent(be.getValueObject(), PIEvent.SELECTION_AREA_CHANGED3);
       
  1944 
       
  1945 			// get new thread counts and loads
       
  1946 			Vector<ProfiledGeneric> traceThreads  = trace.getIndexedThreads();
       
  1947 			Vector<ProfiledGeneric> graphThreads  = this.myGraph.getProfiledThreads();
       
  1948 			Hashtable<String,String> foundThreads = new Hashtable<String,String>();
       
  1949 
       
  1950 			// previous threads are not necessarily graphed this time
       
  1951 			Enumeration<ProfiledGeneric> enu = graphThreads.elements();
       
  1952 			while (enu.hasMoreElements()) {
       
  1953 				ProfiledThread pThread = (ProfiledThread) enu.nextElement();
       
  1954 				pThread.setEnabled(graphIndex, false);
       
  1955 			}
       
  1956 			graphThreads.clear();
       
  1957 
       
  1958 			ProfiledThreshold thresholdThread = this.myGraph.getThresholdThread();
       
  1959 
       
  1960 			if (thresholdThread.isEnabled(graphIndex)) {
       
  1961 				ArrayList<ProfiledGeneric> items = thresholdThread.getItems(graphIndex);
       
  1962 				// disable all items below the threshold
       
  1963 				for (int i = 0; i < items.size(); i++) {
       
  1964 					items.get(i).setEnabled(graphIndex, false);
       
  1965 				}
       
  1966 			}
       
  1967 
       
  1968 			GppSample[] sortedSamples = trace.getSortedGppSamples();
       
  1969 
       
  1970 			// set up in case we find threads below the threshold
       
  1971 			boolean lowThread;
       
  1972 			thresholdThread.init(graphIndex);
       
  1973 
       
  1974 			int threadThreshold = (Integer) NpiInstanceRepository.getInstance().activeUidGetPersistState("com.nokia.carbide.cpp.pi.address.thresholdCountThread"); //$NON-NLS-1$
       
  1975 			for (int i = startSampleIndex; i < endSampleIndex; i++) {
       
  1976 				GppSample sample = sortedSamples[i];
       
  1977 
       
  1978 				ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex);
       
  1979 				if (pBinary.isEnabled(graphIndex)) {
       
  1980 					// thread list is based on binaries
       
  1981 					ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex);
       
  1982 					String threadName = pThread.getNameString();
       
  1983 
       
  1984 					lowThread = pThread.getTotalSampleCount() < threadThreshold;
       
  1985 
       
  1986 					if (!foundThreads.containsKey(threadName)) {
       
  1987 						foundThreads.put(threadName, threadName);
       
  1988 						if (lowThread) {
       
  1989 							thresholdThread.addItem(graphIndex, pThread, 1);
       
  1990 						} else {
       
  1991 							pThread.setEnabled(graphIndex, true);
       
  1992 							pThread.setSampleCount(graphIndex, 1);
       
  1993 							graphThreads.add(pThread);
       
  1994 						}
       
  1995 					} else {
       
  1996 						if (lowThread)
       
  1997 							thresholdThread.incSampleCount(graphIndex);
       
  1998 						else
       
  1999 							pThread.incSampleCount(graphIndex);
       
  2000 					}
       
  2001 				}
       
  2002 			}
       
  2003 
       
  2004 			// set the % load
       
  2005 			for (int i = 0; i < graphThreads.size(); i++) {
       
  2006 				ProfiledThread pThread = (ProfiledThread) graphThreads.elementAt(i);
       
  2007 				pThread.setLoadAndString(graphIndex, (float)(pThread.getSampleCount(graphIndex)*percentPerSample));
       
  2008 			}
       
  2009 			thresholdThread.setLoadAndString(graphIndex,
       
  2010 					(float)(thresholdThread.getSampleCount(graphIndex)*percentPerSample));
       
  2011 
       
  2012 			// update the table items and redraw the table
       
  2013 			this.myGraph.getThreadTable().piEventReceived(be3);
       
  2014 		}
       
  2015 	}
       
  2016 
       
  2017 	public void setSelectedNames()
       
  2018 	{
       
  2019 		Object[] selectedValues = this.tableViewer.getCheckedElements();
       
  2020         String[] functionNames = new String[selectedValues.length];
       
  2021 
       
  2022         for (int i = 0; i < selectedValues.length; i++)
       
  2023 		{
       
  2024 			if (selectedValues[i] instanceof ProfiledFunction)
       
  2025 			{
       
  2026 				ProfiledFunction pf = (ProfiledFunction)selectedValues[i];
       
  2027 				functionNames[i] = pf.getNameString();
       
  2028 			}
       
  2029 		}
       
  2030 
       
  2031         PIVisualSharedData shared = myGraph.getSharedDataInstance();
       
  2032 		shared.GPP_SelectedFunctionNames = functionNames;
       
  2033 	}
       
  2034 
       
  2035 	private class SharedCheckHandler implements ICheckStateListener
       
  2036 	{
       
  2037 		public void checkStateChanged(CheckStateChangedEvent event) {
       
  2038 
       
  2039        		if (!(event.getElement() instanceof ProfiledGeneric))
       
  2040        			return;
       
  2041        		
       
  2042        		// set the stored value to the checkbox value
       
  2043        		ProfiledGeneric pg = (ProfiledGeneric)event.getElement();
       
  2044 	        pg.setEnabled(myGraph.getGraphIndex(), event.getChecked());
       
  2045  
       
  2046 	        // this table's set of checkbox-selected rows has changed, so propagate that information
       
  2047        		setSelectedNames();
       
  2048 
       
  2049        		if (   (pg.getSampleCount(myGraph.getGraphIndex()) != 0)
       
  2050        			|| (myGraph.getDrawMode() == Defines.FUNCTIONS))
       
  2051        			selectionChangeNotify();
       
  2052 
       
  2053        		table.deselectAll();
       
  2054 		}
       
  2055 	}
       
  2056 
       
  2057 	protected void selectionChangeNotify() {
       
  2058 		PIEvent be = new PIEvent(null, PIEvent.CHANGED_FUNCTION_TABLE);
       
  2059 		myGraph.piEventReceived(be);
       
  2060     }
       
  2061 
       
  2062 	public void sortOnColumnSelection(TableColumn tableColumn) {
       
  2063 		int columnId = ((Integer) tableColumn.getData()).intValue();
       
  2064         if (sortColumn == columnId) {
       
  2065         	// sort in other order
       
  2066         	sortAscending = !sortAscending;
       
  2067         } else {
       
  2068         	// sort in the default order
       
  2069 			switch (columnId)
       
  2070 			{
       
  2071 				case COLUMN_ID_SHOW:
       
  2072 				case COLUMN_ID_PERCENT_LOAD:
       
  2073 				case COLUMN_ID_SAMPLE_COUNT:
       
  2074 				{
       
  2075 	            	// sort in descending order (for checked boxes, this means selected boxes first)
       
  2076 	            	sortAscending = false;
       
  2077 	                break;
       
  2078 				}
       
  2079 				case COLUMN_ID_FUNCTION:
       
  2080 				case COLUMN_ID_START_ADDR:
       
  2081 				case COLUMN_ID_IN_BINARY:
       
  2082 				case COLUMN_ID_IN_BINARY_PATH:
       
  2083 				{
       
  2084 	            	// sort in ascending order
       
  2085 	            	sortAscending = true;
       
  2086 	                break;
       
  2087 				}
       
  2088 				default:
       
  2089 				{
       
  2090 					return;
       
  2091 				}
       
  2092             }
       
  2093         }
       
  2094 		
       
  2095 		sortColumn = columnId;
       
  2096 		quickSort(sortColumn, profiledFunctions);
       
  2097 	}
       
  2098 
       
  2099 	private class ColumnSelectionHandler extends SelectionAdapter
       
  2100 	{
       
  2101 		public void widgetSelected(SelectionEvent e)
       
  2102         {
       
  2103         	// wait for the previous sort to finish
       
  2104         	if (sorting || !(e.widget instanceof TableColumn))
       
  2105         		return;
       
  2106 
       
  2107         	sortOnColumnSelection((TableColumn) e.widget);
       
  2108         }
       
  2109 	}
       
  2110 
       
  2111 	public void updateProfiledAndItemData(boolean setInput)
       
  2112 	{
       
  2113 		tableItemData.clear();
       
  2114 		profiledFunctions.clear();
       
  2115 
       
  2116 		// profiledFunctions and tableItemData contain one entry per table row
       
  2117 		Enumeration<ProfiledGeneric> enu = myGraph.getProfiledFunctions().elements();
       
  2118 		while (enu.hasMoreElements())
       
  2119 		{
       
  2120 			ProfiledFunction nextElement = (ProfiledFunction)enu.nextElement();
       
  2121 			tableItemData.add(nextElement);
       
  2122 			profiledFunctions.add(nextElement);
       
  2123 		}
       
  2124 
       
  2125 		if (myGraph.getThresholdFunction().getItemCount(myGraph.getGraphIndex()) != 0) {
       
  2126 			tableItemData.add(myGraph.getThresholdFunction());
       
  2127 			profiledFunctions.add(myGraph.getThresholdFunction());
       
  2128 		}
       
  2129 
       
  2130 		// now sort the items in increasing total sample count, so that they graph correctly
       
  2131 		Object[] sorted = myGraph.getProfiledFunctions().toArray();
       
  2132 		Arrays.sort(sorted, new Comparator<Object>() {
       
  2133 			
       
  2134 			public int compare(Object arg0, Object arg1)
       
  2135 			{
       
  2136 				if (arg0 instanceof ProfiledGeneric && arg1 instanceof ProfiledGeneric)
       
  2137 					return ((ProfiledGeneric)arg0).getTotalSampleCount() -
       
  2138 							((ProfiledGeneric)arg1).getTotalSampleCount();
       
  2139 				else
       
  2140 					return 0;
       
  2141 			}
       
  2142 		});
       
  2143 
       
  2144 		// now create the sorted list used to draw the graph
       
  2145 		myGraph.getSortedFunctions().clear();
       
  2146 
       
  2147 		if (myGraph.getThresholdFunction().getItemCount(myGraph.getGraphIndex()) != 0)
       
  2148 			myGraph.getSortedFunctions().add(myGraph.getThresholdFunction());
       
  2149 
       
  2150 		for (int i = 0; i < sorted.length; i++)
       
  2151 			myGraph.getSortedFunctions().add((ProfiledGeneric) sorted[i]);
       
  2152 
       
  2153 		// refresh the table, if needed
       
  2154 		if (setInput)
       
  2155 			refreshTableViewer();
       
  2156 	}
       
  2157 	
       
  2158 	public void quickSort(int sortBy, Vector<ProfiledGeneric> profiled)
       
  2159 	{
       
  2160 		if (profiled.size() == 0)
       
  2161 			return;
       
  2162 
       
  2163 		this.sorting = true;
       
  2164 
       
  2165 		ProfiledGeneric pGeneric = profiled.elementAt(profiled.size() - 1);
       
  2166 
       
  2167 		if (pGeneric instanceof ProfiledThreshold) {
       
  2168 			profiled.removeElementAt(profiled.size() - 1);
       
  2169 		}
       
  2170 
       
  2171 		this.sorter.setupSort(sortBy, this.myGraph.getGraphIndex(), sortAscending);
       
  2172 
       
  2173 		switch (sortBy) {
       
  2174 			case COLUMN_ID_SHOW:
       
  2175 			{
       
  2176 			    this.sorter.quickSortByShow(profiled);
       
  2177 		        break;
       
  2178 			}
       
  2179 			case COLUMN_ID_PERCENT_LOAD:
       
  2180 			{
       
  2181 			    this.sorter.quickSortByAverageLoad(profiled);
       
  2182 		        break;
       
  2183 			}
       
  2184 			case COLUMN_ID_THREAD:
       
  2185 			{
       
  2186 			    this.sorter.quickSortByThread(profiled);
       
  2187 	            break;
       
  2188 			}
       
  2189 			case COLUMN_ID_BINARY:
       
  2190 			{
       
  2191 			    this.sorter.quickSortByBinary(profiled);
       
  2192 	            break;
       
  2193 			}
       
  2194 			case COLUMN_ID_FUNCTION:
       
  2195 			{
       
  2196 			    this.sorter.quickSortByFunction(profiled);
       
  2197 	            break;
       
  2198 			}
       
  2199 			case COLUMN_ID_SAMPLE_COUNT:
       
  2200 			{
       
  2201 			    this.sorter.quickSortBySampleCount(profiled);
       
  2202 	            break;
       
  2203 			}
       
  2204 			case COLUMN_ID_START_ADDR:
       
  2205 			{
       
  2206 			    this.sorter.quickSortByStartAddress(profiled);
       
  2207 	            break;
       
  2208 			}
       
  2209 			case COLUMN_ID_IN_BINARY:
       
  2210 			{
       
  2211 			    this.sorter.quickSortByAssocBinary(profiled);
       
  2212 	            break;
       
  2213 			}
       
  2214 			case COLUMN_ID_IN_BINARY_PATH:
       
  2215 			{
       
  2216 			    this.sorter.quickSortByAssocBinaryPath(profiled);
       
  2217 	            break;
       
  2218 			}
       
  2219 			case COLUMN_ID_FULL_IN_PATH:
       
  2220 			{
       
  2221 			    this.sorter.quickSortByFullAssocBinaryPath(profiled);
       
  2222 	            break;
       
  2223 			}
       
  2224 			default:
       
  2225 			{
       
  2226 				break;
       
  2227 			}
       
  2228 		}
       
  2229  		
       
  2230 		Enumeration<ProfiledGeneric> e = this.sorter.getSortedList().elements();
       
  2231 		tableItemData = setTableItemData(e);
       
  2232 		if (pGeneric instanceof ProfiledThreshold) {
       
  2233 			tableItemData.add(pGeneric);
       
  2234 			profiled.add(pGeneric);
       
  2235 		}
       
  2236 		
       
  2237 		// find the column corresponding to sortBy, and give it a column direction
       
  2238 		// NOTE: treat sort by binary path then by binary name as sort by path
       
  2239 		if (sortBy == COLUMN_ID_FULL_PATH)
       
  2240 			sortBy = COLUMN_ID_PATH;
       
  2241 		else if (sortBy == COLUMN_ID_FULL_IN_PATH)
       
  2242 			sortBy = COLUMN_ID_IN_BINARY_PATH;
       
  2243 
       
  2244 		TableColumn sortByColumn = null;
       
  2245 		for (int i = 0; i < this.table.getColumnCount(); i++) {
       
  2246 			if (this.table.getColumn(i).getData() instanceof Integer) {
       
  2247 				if (((Integer)this.table.getColumn(i).getData()) == sortBy) {
       
  2248 					sortByColumn = this.table.getColumn(i);
       
  2249 					break;
       
  2250 				}
       
  2251 			}
       
  2252 		}
       
  2253 
       
  2254 		if (sortByColumn != null) {
       
  2255 			this.table.setSortColumn(sortByColumn);
       
  2256 			this.table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN);
       
  2257 		}
       
  2258 
       
  2259 		refreshTableViewer();
       
  2260 		this.sorting = false;
       
  2261 	}
       
  2262 
       
  2263 	protected Menu getTableMenu(Decorations parent, int graphIndex, int drawMode) {
       
  2264 		// get rid of last Menu created so we don't have double menu
       
  2265 		// in on click
       
  2266 		if (contextMenu != null) {
       
  2267 			contextMenu.dispose();
       
  2268 		}
       
  2269 		
       
  2270 		contextMenu = new Menu(parent, SWT.POP_UP);
       
  2271 
       
  2272 		// Use drawMode to determine the drill down items and
       
  2273 		// whether to show a color column
       
  2274 		addDrillDownItems(contextMenu, drawMode);
       
  2275 		
       
  2276 		// sort by path, then binary
       
  2277 		new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2278 		getSortInFullPathItem(contextMenu, this.table.getItemCount() > 0);
       
  2279 
       
  2280 		// check and uncheck boxes
       
  2281 		new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2282 		getCheckRows(contextMenu, this.table.getSelectionCount() > 0);
       
  2283 		
       
  2284 		// select all, copy, and copy all
       
  2285 		new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2286 		getSelectAllItem(contextMenu, this.table.getItemCount() > 0);
       
  2287 		getCopyItem(contextMenu, this.table.getSelectionCount() > 0);
       
  2288 		getCopyTableItem(contextMenu, this.table.getItemCount() > 0);
       
  2289 		
       
  2290 		// copy drilldown tables, if in drilldown mode
       
  2291 		switch (drawMode)
       
  2292 		{
       
  2293 			case Defines.THREADS:
       
  2294 			case Defines.BINARIES:
       
  2295 			case Defines.FUNCTIONS:
       
  2296 				getCopyDrilldownItem(contextMenu, false);
       
  2297 				break;
       
  2298 			default:
       
  2299 				getCopyDrilldownItem(contextMenu, true);
       
  2300 				break;
       
  2301 		}
       
  2302 		
       
  2303 		// save all and save drilldown tables, if in drilldown mode 
       
  2304 		new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2305 		getSaveTableItem(contextMenu, this.table.getItemCount() > 0);
       
  2306 		
       
  2307 		switch (drawMode)
       
  2308 		{
       
  2309 			case Defines.THREADS:
       
  2310 			case Defines.BINARIES:
       
  2311 			case Defines.FUNCTIONS:
       
  2312 				getSaveDrilldownItem(contextMenu, false);
       
  2313 				break;
       
  2314 			default:
       
  2315 				getSaveDrilldownItem(contextMenu, true);
       
  2316 				break;
       
  2317 		}
       
  2318 		
       
  2319 		// save raw samples
       
  2320 		boolean haveSamples = false;
       
  2321 		for (int i = 0; !haveSamples && i < profiledFunctions.size(); i++) {
       
  2322 			ProfiledGeneric pg = profiledFunctions.get(i);
       
  2323 			haveSamples = pg.isEnabled(graphIndex) && pg.getSampleCount(graphIndex) > 0;
       
  2324 		}
       
  2325 
       
  2326 		double startTime = PIPageEditor.currentPageEditor().getStartTime();
       
  2327 		double endTime   = PIPageEditor.currentPageEditor().getEndTime();
       
  2328 		if (!haveSamples || (startTime == -1) || (endTime   == -1) || (startTime == endTime))
       
  2329 			getSaveSamplesItem(contextMenu, Messages.getString("AddrFunctionTable.functions"), false); //$NON-NLS-1$
       
  2330 		else
       
  2331 			getSaveSamplesItem(contextMenu, Messages.getString("AddrFunctionTable.functions"), true); //$NON-NLS-1$
       
  2332 
       
  2333 		// recolor selected threads
       
  2334 		switch (drawMode)
       
  2335 		{
       
  2336 			case Defines.FUNCTIONS:
       
  2337 			case Defines.THREADS_BINARIES_FUNCTIONS:
       
  2338 			case Defines.BINARIES_FUNCTIONS:
       
  2339 			case Defines.THREADS_FUNCTIONS:
       
  2340 			case Defines.BINARIES_THREADS_FUNCTIONS:
       
  2341 			{
       
  2342 				// recolor selected items
       
  2343 				new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2344 				getRecolorItem(contextMenu, Messages.getString("AddressPlugin.functions"),   //$NON-NLS-1$
       
  2345 								this.table.getSelectionCount() > 0);
       
  2346 				break;
       
  2347 			}
       
  2348 			case Defines.THREADS_FUNCTIONS_BINARIES:
       
  2349 			case Defines.BINARIES_FUNCTIONS_THREADS:
       
  2350 			case Defines.FUNCTIONS_THREADS:
       
  2351 			case Defines.FUNCTIONS_THREADS_BINARIES:
       
  2352 			case Defines.FUNCTIONS_BINARIES:
       
  2353 			case Defines.FUNCTIONS_BINARIES_THREADS:
       
  2354 			{
       
  2355 				break;
       
  2356 			}
       
  2357 			default:
       
  2358 				break;
       
  2359 		}
       
  2360 
       
  2361 		new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2362 		getChangeThresholds(contextMenu);
       
  2363 
       
  2364 		switch (drawMode) {
       
  2365 			case Defines.THREADS_FUNCTIONS:
       
  2366 			case Defines.THREADS_BINARIES_FUNCTIONS:
       
  2367 			case Defines.BINARIES_FUNCTIONS:
       
  2368 			case Defines.BINARIES_THREADS_FUNCTIONS:	
       
  2369 			case Defines.FUNCTIONS:
       
  2370 				new MenuItem(contextMenu, SWT.SEPARATOR);
       
  2371 				// source look up only when one item is selected
       
  2372 				if (table.getSelection().length == 1) {
       
  2373 					getSourceLookUpItem(contextMenu, Messages.getString("AddrFunctionTable.items"));  //$NON-NLS-1$
       
  2374 				} else {
       
  2375 					getDisabledSourceLookUpItem(contextMenu, Messages.getString("AddrFunctionTable.items"));  //$NON-NLS-1$
       
  2376 				}
       
  2377 			default:
       
  2378 				break;
       
  2379 		}
       
  2380 
       
  2381 		contextMenu.setVisible(true);
       
  2382 
       
  2383 		return contextMenu;
       
  2384 	}
       
  2385 
       
  2386 	public Vector getTableItemData() {
       
  2387 		return this.tableItemData;
       
  2388 	}
       
  2389 
       
  2390 }