Java tutorial
/* * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * This component and the accompanying materials are made available * under the terms of the License "Eclipse Public License v1.0" * which accompanies this distribution, and is available * at the URL "http://www.eclipse.org/legal/epl-v10.html". * * Initial Contributors: * Nokia Corporation - initial contribution. * * Contributors: * * Description: * */ package com.nokia.carbide.cpp.pi.address; import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.StringSelection; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Enumeration; import java.util.Vector; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ActionContributionItem; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionManager; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.SubMenuManager; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusListener; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Decorations; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.IActionBars; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.ide.IIDEActionConstants; import com.nokia.carbide.cpp.internal.pi.address.GppModelAdapter; import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples; import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveTable; import com.nokia.carbide.cpp.internal.pi.model.ProfiledBinary; import com.nokia.carbide.cpp.internal.pi.model.ProfiledFunction; import com.nokia.carbide.cpp.internal.pi.model.ProfiledGeneric; import com.nokia.carbide.cpp.internal.pi.model.ProfiledThread; import com.nokia.carbide.cpp.internal.pi.model.ProfiledThreshold; import com.nokia.carbide.cpp.internal.pi.save.SaveTableWizard; import com.nokia.carbide.cpp.internal.pi.visual.Defines; import com.nokia.carbide.cpp.internal.pi.visual.GenericTable; import com.nokia.carbide.cpp.pi.editors.PIPageEditor; public abstract class GenericAddrTable extends GenericTable { protected GppTraceGraph myGraph; protected Composite parent; protected GppModelAdapter adapter; // sorting column and order protected int sortColumn = COLUMN_ID_SAMPLE_COUNT; protected boolean sortAscending; protected GppTableSorter sorter; protected boolean sorting = false; abstract protected Menu getTableMenu(Decorations parent, int graphIndex, int drawMode); protected boolean isDrilldown = false; // menu items protected Action selectAllAction; protected Action copyTableAction; protected Action copyAction; protected Action copyDrilldownAction; protected Action saveTableAction; protected Action saveDrilldownAction; protected static int SAMPLES_AT_ONE_TIME = 1000; public GenericAddrTable(GppTraceGraph myGraph, Composite parent, GppModelAdapter adapter) { this.myGraph = myGraph; this.parent = parent; this.adapter = adapter; } // class to pass sample data to the save wizard public class SaveSampleString implements ISaveSamples { int graphIndex; int drawMode; int startIndex = 0; public SaveSampleString(int graphIndex, int drawMode) { this.graphIndex = graphIndex; this.drawMode = drawMode; } public String getData() { return getData(SAMPLES_AT_ONE_TIME); } public String getData(int size) { String returnString = getSampleString(graphIndex, drawMode, this.startIndex, this.startIndex + size); if (returnString == null) this.startIndex = 0; else this.startIndex += size; return returnString; } public int getIndex() { return this.startIndex; } public void clear() { this.startIndex = 0; } } protected MenuItem getSaveSamplesItem(Menu menu, String sampleType, boolean enabled) { MenuItem saveSamplesItem = new MenuItem(menu, SWT.PUSH); saveSamplesItem.setText(Messages.getString("GenericAddrTable.saveSamples1") + sampleType //$NON-NLS-1$ + Messages.getString("GenericAddrTable.saveSamples2")); //$NON-NLS-1$ saveSamplesItem.setEnabled(enabled); if (enabled) { saveSamplesItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("saveSamples"); //$NON-NLS-1$ } }); } return saveSamplesItem; } public GppTraceGraph getGraph() { return myGraph; } protected class TableMouseListener implements MouseListener { public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { if (e.button == MouseEvent.BUTTON1) { TableItem[] selectedItems = table.getSelection(); if (selectedItems.length == 0) return; if (selectedItems[0].getData() instanceof ProfiledGeneric) { ProfiledGeneric pg = (ProfiledGeneric) (selectedItems[0].getData()); if (pg.isEnabled(myGraph.getGraphIndex())) action("remove"); //$NON-NLS-1$ else action("add"); //$NON-NLS-1$ action("doubleClick"); //$NON-NLS-1$ } } } public void mouseDown(org.eclipse.swt.events.MouseEvent e) { } public void mouseUp(org.eclipse.swt.events.MouseEvent e) { if (e.button == MouseEvent.BUTTON3) { Menu menu = getTableMenu(table.getShell(), myGraph.getGraphIndex(), myGraph.getDrawMode()); menu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y)); table.setMenu(menu); } } } public void setVisualisationColumnVisible(boolean flag) { } public void valueChanged(SelectionEvent e) { } protected Vector<ProfiledGeneric> setTableItemData(Enumeration<ProfiledGeneric> enu) { Vector<ProfiledGeneric> tmpItems = new Vector<ProfiledGeneric>(); while (enu.hasMoreElements()) { tmpItems.add(enu.nextElement()); } return tmpItems; } protected void addDrillDownItems(Menu tableMenu, int drawMode) { switch (drawMode) { case Defines.THREADS: { // thread drill down items threadItem(tableMenu, true); threadBinaryItem(tableMenu, false); threadFunctionItem(tableMenu, false); break; } case Defines.THREADS_BINARIES: { // thread drill down items threadItem(tableMenu, false); threadBinaryItem(tableMenu, true); threadBinaryFunctionItem(tableMenu, false); break; } case Defines.THREADS_BINARIES_FUNCTIONS: { // thread drill down items threadItem(tableMenu, false); threadBinaryItem(tableMenu, false); threadBinaryFunctionItem(tableMenu, true); break; } case Defines.THREADS_FUNCTIONS: { // thread drill down items threadItem(tableMenu, false); threadFunctionItem(tableMenu, true); newThreadFunctionBinary(tableMenu, false); break; } case Defines.THREADS_FUNCTIONS_BINARIES: { // thread drill down items threadItem(tableMenu, false); threadFunctionItem(tableMenu, false); newThreadFunctionBinary(tableMenu, true); break; } case Defines.BINARIES: { // binary drill down items binaryItem(tableMenu, true); binaryThreadItem(tableMenu, false); binaryFunctionItem(tableMenu, false); break; } case Defines.BINARIES_THREADS: { // binary drill down items binaryItem(tableMenu, false); binaryThreadItem(tableMenu, true); binaryThreadFunctionItem(tableMenu, false); break; } case Defines.BINARIES_THREADS_FUNCTIONS: { // binary drill down items binaryItem(tableMenu, false); binaryThreadItem(tableMenu, false); binaryThreadFunctionItem(tableMenu, true); break; } case Defines.BINARIES_FUNCTIONS: { // binary drill down items binaryItem(tableMenu, false); binaryFunctionItem(tableMenu, true); binaryFunctionThreadItem(tableMenu, false); break; } case Defines.BINARIES_FUNCTIONS_THREADS: { // binary drill down items binaryItem(tableMenu, false); binaryFunctionItem(tableMenu, false); binaryFunctionThreadItem(tableMenu, true); break; } case Defines.FUNCTIONS: { // function drill down items functionItem(tableMenu, true); functionThreadItem(tableMenu, false); functionBinaryItem(tableMenu, false); break; } case Defines.FUNCTIONS_THREADS: { // function drill down items functionItem(tableMenu, false); functionThreadItem(tableMenu, true); functionThreadBinaryItem(tableMenu, false); break; } case Defines.FUNCTIONS_THREADS_BINARIES: { // function drill down items functionItem(tableMenu, false); functionThreadItem(tableMenu, false); functionThreadBinaryItem(tableMenu, true); break; } case Defines.FUNCTIONS_BINARIES: { // function drill down items functionItem(tableMenu, false); functionBinaryItem(tableMenu, true); functionBinaryThreadItem(tableMenu, false); break; } case Defines.FUNCTIONS_BINARIES_THREADS: { // function drill down items functionItem(tableMenu, false); functionBinaryItem(tableMenu, false); functionBinaryThreadItem(tableMenu, true); break; } default: break; } } //unused? // /* // * Find if any threads with checkboxes checked // */ // protected boolean haveCheckedThread(GppTrace trace, int graphIndex) // { // ProfiledThread pThread; // for (ProfiledGeneric pGeneric: trace.getIndexedThreads()) { // if (pGeneric instanceof ProfiledThread) { // pThread = (ProfiledThread) pGeneric; // if (pThread.isEnabled(graphIndex)) // return true; // } // } // return false; // } // // // /* // * Find if any binaries with checkboxes checked // */ // protected boolean haveCheckedBinary(GppTrace trace, int graphIndex) // { // ProfiledBinary pBinary; // for (ProfiledGeneric pGeneric: trace.getIndexedBinaries()) { // if (pGeneric instanceof ProfiledBinary) { // pBinary = (ProfiledBinary) pGeneric; // if (pBinary.isEnabled(graphIndex)) // return true; // } // } // return false; // } // // /* // * Find if any functions with checkboxes checked // */ // protected boolean haveCheckedFunction(GppTrace trace, int graphIndex) // { // ProfiledFunction pFunction; // for (ProfiledGeneric pGeneric: trace.getIndexedFunctions()) { // if (pGeneric instanceof ProfiledFunction) { // pFunction = (ProfiledFunction) pGeneric; // if (pFunction.isEnabled(graphIndex)) // return true; // } // } // return false; // } /* * get list of matching samples based on draw mode */ private ArrayList<GppSample> getMatchingSamples(int drawMode, GppTrace trace, int startIndex, int endIndex, int graphIndex) { ArrayList<GppSample> samplesArray = new ArrayList<GppSample>( endIndex - startIndex > 1000 ? 1000 : endIndex - startIndex); Vector<ProfiledThread> traceThreads = trace.getIndexedThreads(); Vector<ProfiledBinary> traceBinaries = trace.getIndexedBinaries(); Vector<ProfiledFunction> traceFunctions = trace.getIndexedFunctions(); GppSample[] samples = trace.getSortedGppSamples(); GppSample sample; switch (drawMode) { case Defines.THREADS: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex); if (pThread.isEnabled(graphIndex)) samplesArray.add(sample); } break; case Defines.BINARIES: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex); if (pBinary.isEnabled(graphIndex)) samplesArray.add(sample); } break; case Defines.FUNCTIONS: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex); if (pFunction.isEnabled(graphIndex)) samplesArray.add(sample); } break; case Defines.THREADS_BINARIES: case Defines.BINARIES_THREADS: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex); if (pThread.isEnabled(graphIndex)) { ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex); if (pBinary.isEnabled(graphIndex)) { samplesArray.add(sample); } } } break; case Defines.THREADS_FUNCTIONS: case Defines.FUNCTIONS_THREADS: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex); if (pThread.isEnabled(graphIndex)) { ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex); if (pFunction.isEnabled(graphIndex)) { samplesArray.add(sample); } } } break; case Defines.BINARIES_FUNCTIONS: case Defines.FUNCTIONS_BINARIES: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex); if (pBinary.isEnabled(graphIndex)) { ProfiledFunction pFunction = (ProfiledFunction) traceFunctions.elementAt(sample.functionIndex); if (pFunction.isEnabled(graphIndex)) { samplesArray.add(sample); } } } break; case Defines.THREADS_FUNCTIONS_BINARIES: case Defines.THREADS_BINARIES_FUNCTIONS: for (int i = startIndex; i < endIndex; i++) { sample = samples[i]; ProfiledThread pThread = (ProfiledThread) traceThreads.elementAt(sample.threadIndex); if (pThread.isEnabled(graphIndex)) { ProfiledBinary pBinary = (ProfiledBinary) traceBinaries.elementAt(sample.binaryIndex); if (pBinary.isEnabled(graphIndex)) { ProfiledFunction pFunction = (ProfiledFunction) traceFunctions .elementAt(sample.functionIndex); if (pFunction.isEnabled(graphIndex)) { samplesArray.add(sample); } } } } break; } samplesArray.trimToSize(); return samplesArray; } /* * return the thread, binary, or function samples selected in the interval */ protected String getSampleString(int graphIndex, int drawMode, int startIndex, int endIndex) { boolean threads = false; boolean binaries = false; boolean functions = false; GppTraceGraph graph = (GppTraceGraph) (this.myGraph); GppTrace trace = (GppTrace) (graph.getTrace()); // The current graph shows either threads, binaries, or functions switch (drawMode) { case Defines.THREADS: case Defines.BINARIES_THREADS: case Defines.BINARIES_FUNCTIONS_THREADS: case Defines.FUNCTIONS_THREADS: case Defines.FUNCTIONS_BINARIES_THREADS: threads = true; break; case Defines.BINARIES: case Defines.THREADS_BINARIES: case Defines.THREADS_FUNCTIONS_BINARIES: case Defines.FUNCTIONS_BINARIES: case Defines.FUNCTIONS_THREADS_BINARIES: binaries = true; break; case Defines.FUNCTIONS: case Defines.THREADS_FUNCTIONS: case Defines.THREADS_BINARIES_FUNCTIONS: case Defines.BINARIES_FUNCTIONS: case Defines.BINARIES_THREADS_FUNCTIONS: functions = true; break; default: break; } int startTime = trace.getStartSampleIndex(); int endTime = trace.getEndSampleIndex(); // check if we have returned everything if (startIndex > (endTime - startTime)) return null; ArrayList<GppSample> matchingSamples = getMatchingSamples(drawMode, trace, startTime, endTime, graphIndex); String returnString = ""; //$NON-NLS-1$ if (threads) { Vector<ProfiledThread> traceThreads = trace.getIndexedThreads(); if (startIndex == 0) returnString = Messages.getString("GenericAddrTable.threadSampleHeading"); //$NON-NLS-1$ for (int i = startIndex; i < matchingSamples.size() && i < endIndex; i++) { GppSample sample = matchingSamples.get(i); returnString += sample.sampleSynchTime + ",0x" + Long.toHexString(sample.programCounter) + "," //$NON-NLS-1$ //$NON-NLS-2$; $NON-NLS-2$; + traceThreads.get(sample.threadIndex).getNameString() + "\n"; //$NON-NLS-1$ } } else if (binaries) { if (startIndex == 0) returnString = Messages.getString("GenericAddrTable.binarySampleHeading"); //$NON-NLS-1$ for (int i = startIndex; i < matchingSamples.size() && i < endIndex; i++) { GppSample sample = matchingSamples.get(i); ProfiledBinary binary = (ProfiledBinary) trace.getIndexedBinaries().get(sample.binaryIndex); returnString += sample.sampleSynchTime + ",0x" + Long.toHexString(sample.programCounter) + "," //$NON-NLS-1$ //$NON-NLS-2$; $NON-NLS-2$; + binary.getNameString() + "\n"; // $NON-NLS-1$; //$NON-NLS-1$ } } else if (functions) { if (startIndex == 0) returnString = Messages.getString("GenericAddrTable.functionSampleHeading"); //$NON-NLS-1$ for (int i = startIndex; i < matchingSamples.size() && i < endIndex; i++) { GppSample sample = matchingSamples.get(i); ProfiledFunction function = (ProfiledFunction) trace.getIndexedFunctions() .get(sample.functionIndex); returnString += sample.sampleSynchTime + ",0x" + Long.toHexString(sample.programCounter) + ",\"" //$NON-NLS-1$ //$NON-NLS-2$; $NON-NLS-2$; + function.getNameString() + "\",0x" + Long.toHexString(function.getFunctionAddress()) //$NON-NLS-1$ + "\n"; //$NON-NLS-1$; $NON-NLS-2$; } } return returnString; } private void threadItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.threadOnly")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("thread-only"); //$NON-NLS-1$ } }); } private void threadBinaryItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.threadBinary")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("thread-binary"); //$NON-NLS-1$ } }); } private void threadBinaryFunctionItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.threadBinaryFunction")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("thread-binary-function"); //$NON-NLS-1$ } }); } private void threadFunctionItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.threadFunction")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("thread-function"); //$NON-NLS-1$ } }); } private void newThreadFunctionBinary(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.threadFunctionBinary")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("thread-function-binary"); //$NON-NLS-1$ } }); } private void binaryItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.binaryOnly")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("binary-only"); //$NON-NLS-1$ } }); } private void binaryThreadItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.binaryThread")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("binary-thread"); //$NON-NLS-1$ } }); } private void binaryThreadFunctionItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.binaryThreadFunction")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("binary-thread-function"); //$NON-NLS-1$ } }); } private void binaryFunctionItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.binaryFunction")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("binary-function"); //$NON-NLS-1$ } }); } private void binaryFunctionThreadItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.binaryFunctionThread")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("binary-function-thread"); //$NON-NLS-1$ } }); } private void functionItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.functionOnly")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("function-only"); //$NON-NLS-1$ } }); } private void functionThreadItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.functionThread")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("function-thread"); //$NON-NLS-1$ } }); } private void functionThreadBinaryItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.functionThreadBinary")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("function-thread-binary"); //$NON-NLS-1$ } }); } private void functionBinaryItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.functionBinary")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("function-binary"); //$NON-NLS-1$ } }); } private void functionBinaryThreadItem(Menu menu, boolean chosen) { MenuItem menuItem = new MenuItem(menu, SWT.RADIO); menuItem.setText(Messages.getString("GenericAddrTable.functionBinaryThread")); //$NON-NLS-1$ menuItem.setSelection(chosen); menuItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("function-binary-thread"); //$NON-NLS-1$ } }); } protected String copyDrilldown(int tableCount, Table[] tables, String separator) { // make sure it's a valid drilldown if ((tableCount < 2) || (tableCount > 3) || (tables[0] == null) || (tables[1] == null) || (tableCount == 2 && tables[2] != null) || (tableCount == 3 && tables[2] == null)) return ""; //$NON-NLS-1$ String copyString = ""; //$NON-NLS-1$ // create the multiple table heading line (e.g., "Threads Binaries") // space them out based on how many columns are in their table for (int i = 0; i < tableCount; i++) { if (tables[i].getData() instanceof String) { copyString += (String) (tables[i].getData()); } for (int j = 0; j < tables[i].getColumnCount(); j++) { copyString += separator; } } copyString += "\n"; //$NON-NLS-1$ // create the multiple table column headings for (int i = 0; i < tableCount; i++) { if (i != tableCount - 1) { copyString += copyHeading(tables[i], CHECKBOX_NO_TEXT, separator, separator); //$NON-NLS-1$ } else { copyString += copyHeading(tables[i], CHECKBOX_NO_TEXT, separator, "\n"); //$NON-NLS-1$ } } // determine the row, column count, and column ordering in each table int rowCount0 = tables[0].getItemCount(); int columnCount0 = tables[0].getColumnCount(); int[] columnOrder0 = tables[0].getColumnOrder(); boolean[] isHex0 = (boolean[]) tables[0].getData("isHex"); //$NON-NLS-1$ String emptyRow0 = ""; //$NON-NLS-1$ int rowCount1 = tables[1].getItemCount(); int columnCount1 = tables[1].getColumnCount(); int[] columnOrder1 = tables[1].getColumnOrder(); boolean[] isHex1 = (boolean[]) tables[1].getData("isHex"); //$NON-NLS-1$ String emptyRow1 = ""; //$NON-NLS-1$ int rowCount2 = tableCount > 2 ? tables[2].getItemCount() : 0; int columnCount2 = tableCount > 2 ? tables[2].getColumnCount() : 0; int[] columnOrder2 = tableCount > 2 ? tables[2].getColumnOrder() : null; boolean[] isHex2 = tableCount > 2 ? ((boolean[]) tables[2].getData("isHex")) : null; //$NON-NLS-1$ String emptyRow2 = ""; //$NON-NLS-1$ // determine the number of multiple table rows (max of any table's rows) int rowCount = rowCount0 >= rowCount1 ? rowCount0 : rowCount1; rowCount = rowCount > rowCount2 ? rowCount : rowCount2; // generate empty row strings, to speed things up if (rowCount0 < rowCount) { for (int j = 0; j < columnCount0 - 1; j++) { emptyRow0 += separator; } } if (rowCount1 < rowCount) { for (int j = 0; j < columnCount1; j++) { emptyRow1 += separator; } } if ((tableCount > 2) && (rowCount2 < rowCount)) { for (int j = 0; j < columnCount2; j++) { emptyRow2 += separator; } } // generate the rows for (int i = 0; i < rowCount; i++) { if (i < rowCount0) { copyString += copyRow(isHex0, tables[0].getItem(i), CHECKBOX_NO_TEXT, columnCount0, columnOrder0, separator); } else { copyString += emptyRow0; } if (i < rowCount1) { copyString += separator + copyRow(isHex1, tables[1].getItem(i), CHECKBOX_NO_TEXT, columnCount1, columnOrder1, separator); } else { // NOTE: if this is the last table, or the 3rd table has nothing but empty // rows left, we may not need to fill in these fields copyString += emptyRow1; } if (tableCount > 2) { if (i < rowCount2) { copyString += separator + copyRow(isHex2, tables[2].getItem(i), CHECKBOX_NO_TEXT, columnCount2, columnOrder2, separator); } else { // NOTE: we may not need to fill in the empty fields of the last table copyString += emptyRow2; } } copyString += "\n"; //$NON-NLS-1$ } return copyString; } // class to pass drilldown tables to the save wizard class SaveDrillDownString implements ISaveTable { private int tableCount; private Table[] tables; private String separator; public SaveDrillDownString(int tableCount, Table[] tables, String separator) { this.tableCount = tableCount; this.tables = tables; this.separator = separator; } public String getData() { return copyDrilldown(tableCount, tables, separator); } } public Table[] getDrillDownTables() { // copy all tables in a drilldown to the clipboard or save to a file int drawMode = this.myGraph.getDrawMode(); int tableCount = 0; Table[] tables = new Table[3]; // determine which tables are in the drilldown switch (drawMode) { case Defines.THREADS_BINARIES: tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); break; case Defines.THREADS_BINARIES_FUNCTIONS: tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); break; case Defines.THREADS_FUNCTIONS: tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); break; case Defines.THREADS_FUNCTIONS_BINARIES: tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); break; case Defines.BINARIES_THREADS: tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); break; case Defines.BINARIES_THREADS_FUNCTIONS: tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); break; case Defines.BINARIES_FUNCTIONS: tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); break; case Defines.BINARIES_FUNCTIONS_THREADS: tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); break; case Defines.FUNCTIONS_THREADS: tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); break; case Defines.FUNCTIONS_THREADS_BINARIES: tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); break; case Defines.FUNCTIONS_BINARIES: tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); break; case Defines.FUNCTIONS_BINARIES_THREADS: tables[tableCount++] = this.myGraph.getFunctionTable().getTable(); tables[tableCount++] = this.myGraph.getBinaryTable().getTable(); tables[tableCount++] = this.myGraph.getThreadTable().getTable(); break; default: } return tables; } protected void actionCopyOrSaveDrilldown(boolean doCopy, String separator) { Table[] tables = getDrillDownTables(); int tableCount = 0; while ((tableCount < tables.length) && (tables[tableCount] != null)) tableCount++; if (doCopy) { // change the clipboard contents Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard(); String copyString = copyDrilldown(tableCount, tables, separator); StringSelection contents = new StringSelection(copyString); cb.setContents(contents, contents); } else { // save to a file SaveDrillDownString getString = new SaveDrillDownString(tableCount, tables, separator); WizardDialog dialog; Wizard w = new SaveTableWizard(getString); dialog = new WizardDialog(PlatformUI.getWorkbench().getDisplay().getActiveShell(), w); dialog.open(); } } protected void createDefaultActions() { selectAllAction = new Action("SelectAll") { //$NON-NLS-1$ public void run() { action("selectAll"); //$NON-NLS-1$ } }; selectAllAction.setEnabled(true); copyAction = new Action("Copy") { //$NON-NLS-1$ public void run() { action("copy"); //$NON-NLS-1$ } }; copyAction.setEnabled(false); copyTableAction = new Action("CopyTable") { //$NON-NLS-1$ public void run() { action("copyTable"); //$NON-NLS-1$ } }; copyTableAction.setEnabled(true); copyTableAction.setId("PICopyTable"); //$NON-NLS-1$ copyTableAction.setText(Messages.getString("GenericAddrTable.copyTable")); //$NON-NLS-1$ copyDrilldownAction = new Action("CopyDrilldown") { //$NON-NLS-1$ public void run() { action("copyDrilldown"); //$NON-NLS-1$ } }; copyDrilldownAction.setEnabled(false); copyDrilldownAction.setId("PICopyDrilldown"); //$NON-NLS-1$ copyDrilldownAction.setText(Messages.getString("GenericAddrTable.copyDrilldownTables")); //$NON-NLS-1$ saveTableAction = new Action("SaveTable") { //$NON-NLS-1$ public void run() { action("saveTable"); //$NON-NLS-1$ } }; saveTableAction.setEnabled(true); saveTableAction.setId("PISaveTable"); //$NON-NLS-1$ saveTableAction.setText(Messages.getString("GenericAddrTable.saveTable")); //$NON-NLS-1$ saveDrilldownAction = new Action("SaveDrilldown") { //$NON-NLS-1$ public void run() { action("saveDrilldown"); //$NON-NLS-1$ } }; saveDrilldownAction.setEnabled(false); saveDrilldownAction.setId("PISaveDrilldown"); //$NON-NLS-1$ saveDrilldownAction.setText(Messages.getString("GenericAddrTable.saveDrilldownTables")); //$NON-NLS-1$ // saveSamplesAction = new Action("SaveSamples") { //$NON-NLS-1$ // public void run() { // action("saveSamples"); //$NON-NLS-1$ // } // }; // saveSamplesAction.setEnabled(true); // saveSamplesAction.setId("PISaveAddressSamples"); //$NON-NLS-1$ // saveSamplesAction.setText(Messages.getString("GenericAddrTable.23") + sampleType + Messages.getString("GenericAddrTable.24")); //$NON-NLS-1$ //$NON-NLS-2$ } public void setIsDrilldown(boolean isDrilldown) { this.isDrilldown = isDrilldown; copyDrilldownAction.setEnabled(isDrilldown); saveDrilldownAction.setEnabled(isDrilldown); // may need to clean up stale Edit & File menu entry for PICopyDrilldown and PISaveDrilldown if (!isDrilldown) { IMenuManager editMenuManager = PIPageEditor.getActionBars().getMenuManager() .findMenuUsingPath(IIDEActionConstants.M_EDIT); if (editMenuManager instanceof SubMenuManager) { IContributionManager editManager = ((SubMenuManager) editMenuManager).getParent(); ActionContributionItem item; editMenuManager.remove("PICopyDrilldown"); //$NON-NLS-1$ item = new ActionContributionItem(copyDrilldownAction); item.setVisible(true); editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item); editMenuManager.remove("PICopyTable"); //$NON-NLS-1$ copyTableAction.setEnabled(table.getItemCount() > 0); item = new ActionContributionItem(copyTableAction); item.setVisible(true); editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item); } IMenuManager fileMenuManager = PIPageEditor.getActionBars().getMenuManager() .findMenuUsingPath(IIDEActionConstants.M_FILE); if (fileMenuManager instanceof SubMenuManager) { IContributionManager fileManager = ((SubMenuManager) fileMenuManager).getParent(); ActionContributionItem item; fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$ saveTableAction.setEnabled(table.getItemCount() > 0); item = new ActionContributionItem(saveTableAction); item.setVisible(true); fileManager.insertAfter("saveAll", item); //$NON-NLS-1$ fileMenuManager.remove("PISaveDrilldown"); //$NON-NLS-1$ item = new ActionContributionItem(saveDrilldownAction); item.setVisible(true); fileManager.insertAfter("PISaveTable", item); //$NON-NLS-1$ fileManager.update(true); } } } protected MenuItem getCopyDrilldownItem(Menu menu, boolean enabled) { MenuItem copyDrilldownItem = new MenuItem(menu, SWT.PUSH); copyDrilldownItem.setText(Messages.getString("GenericAddrTable.copyDrilldownTables")); //$NON-NLS-1$ copyDrilldownItem.setEnabled(enabled); if (enabled) { copyDrilldownItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("copyDrilldown"); //$NON-NLS-1$ } }); } return copyDrilldownItem; } protected MenuItem getSaveDrilldownItem(Menu menu, boolean enabled) { MenuItem saveDrilldownItem = new MenuItem(menu, SWT.PUSH); saveDrilldownItem.setText(Messages.getString("GenericAddrTable.saveDrilldownTables")); //$NON-NLS-1$ saveDrilldownItem.setEnabled(enabled); if (enabled) { saveDrilldownItem.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { action("saveDrilldown"); //$NON-NLS-1$ } }); } return saveDrilldownItem; } protected class AddrTableFocusListener implements FocusListener { IAction oldSelectAllAction = null; IAction oldCopyAction = null; public void focusGained(org.eclipse.swt.events.FocusEvent arg0) { IActionBars bars = PIPageEditor.getActionBars(); // modify what is executed when Select All and Copy are called from the Edit menu oldSelectAllAction = bars.getGlobalActionHandler(ActionFactory.SELECT_ALL.getId()); oldCopyAction = bars.getGlobalActionHandler(ActionFactory.COPY.getId()); bars.setGlobalActionHandler(ActionFactory.COPY.getId(), copyAction); bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), selectAllAction); copyAction.setEnabled(table.getSelectionCount() > 0); selectAllAction.setEnabled(table.getItemCount() > 0); bars.updateActionBars(); // add to the Edit menu IMenuManager editMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_EDIT); if (editMenuManager instanceof SubMenuManager) { IContributionManager editManager = ((SubMenuManager) editMenuManager).getParent(); ActionContributionItem item; editMenuManager.remove("PICopyDrilldown"); //$NON-NLS-1$ item = new ActionContributionItem(copyDrilldownAction); item.setVisible(true); editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item); editMenuManager.remove("PICopyTable"); //$NON-NLS-1$ copyTableAction.setEnabled(table.getItemCount() > 0); item = new ActionContributionItem(copyTableAction); item.setVisible(true); editManager.prependToGroup(IIDEActionConstants.CUT_EXT, item); } // add to the File menu IMenuManager fileMenuManager = bars.getMenuManager().findMenuUsingPath(IIDEActionConstants.M_FILE); if (fileMenuManager instanceof SubMenuManager) { IContributionManager fileManager = ((SubMenuManager) fileMenuManager).getParent(); ActionContributionItem item; fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$ saveTableAction.setEnabled(table.getItemCount() > 0); item = new ActionContributionItem(saveTableAction); item.setVisible(true); fileManager.insertAfter("saveAll", item); //$NON-NLS-1$ fileMenuManager.remove("PISaveDrilldown"); //$NON-NLS-1$ item = new ActionContributionItem(saveDrilldownAction); item.setVisible(true); fileManager.insertAfter("PISaveTable", item); //$NON-NLS-1$ } } public void focusLost(org.eclipse.swt.events.FocusEvent arg0) { IActionBars bars = PIPageEditor.getActionBars(); bars.setGlobalActionHandler(ActionFactory.COPY.getId(), oldCopyAction); bars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), oldSelectAllAction); bars.updateActionBars(); SubMenuManager editMenuManager = (SubMenuManager) PIPageEditor.getMenuManager() .find(IIDEActionConstants.M_EDIT); editMenuManager.remove("PICopyTable"); //$NON-NLS-1$ editMenuManager.remove("PICopyDrilldown"); //$NON-NLS-1$ SubMenuManager fileMenuManager = (SubMenuManager) PIPageEditor.getMenuManager() .find(IIDEActionConstants.M_FILE); fileMenuManager.remove("PISaveTable"); //$NON-NLS-1$ fileMenuManager.remove("PISaveDrilldown"); //$NON-NLS-1$ } } }