diff -r 615035072f7e -r 844b047e260d sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadTable.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/SwiThreadTable.java Wed Apr 21 15:14:16 2010 +0300 @@ -0,0 +1,497 @@ +/* + * Copyright (c) 2010 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.irq; + +import java.awt.event.MouseEvent; +import java.util.Vector; +import org.eclipse.jface.viewers.CheckStateChangedEvent; +import org.eclipse.jface.viewers.CheckboxTableViewer; +import org.eclipse.jface.viewers.ICheckStateListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.swt.SWT; +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.Menu; +import org.eclipse.swt.widgets.MenuItem; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; +import com.nokia.carbide.cpp.internal.pi.visual.GenericTable; + +/** + * Software thread interrupt table + */ +public class SwiThreadTable extends GenericTable implements ICheckStateListener { + + private IrqTraceGraph myGraph; + private Composite parent; + + protected Vector tableItemData; + + // sort direction + private boolean sortAscending = true; + + /** + * Constructor + * @param myGraph irq graph + * @param parent parent where table is placed + */ + public SwiThreadTable(IrqTraceGraph myGraph, Composite parent){ + this.myGraph = myGraph; + this.parent = parent; + + this.tableViewer = CheckboxTableViewer.newCheckList(parent, + SWT.BORDER | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); + this.table = this.tableViewer.getTable(); + + // add the check state handler, label provider and content provider + this.tableViewer.addCheckStateListener(this); + this.tableViewer.setLabelProvider(new SwiThreadLabelProvider(this.table)); + this.tableViewer.setContentProvider(new TableContentProvider()); + this.tableViewer.setSorter(new SharedSorter()); + + // create the columns + TableColumn column; + + // data associated with the TableViewer will note which columns contain hex values + // Keep this in the order in which columns have been created + boolean[] isHex = {false, false, false, false}; + this.table.setData("isHex", isHex); //$NON-NLS-1$ + + // Check column + column = new TableColumn(this.table, SWT.CENTER); + column.setText(Messages.SwiThreadTable_0); + column.setWidth(20); + column.setData(COLUMN_ID_SWI_CHECK); + column.setMoveable(true); + column.setResizable(true); + column.addSelectionListener(new ColumnSelectionHandler()); + + // Thread Name column + column = new TableColumn(this.table, SWT.LEFT); + column.setText(Messages.SwiThreadTable_1); + column.setWidth(COLUMN_WIDTH_THREAD_IRQ_LINE); + column.setData(COLUMN_ID_SWI_THREAD); + column.setMoveable(true); + column.setResizable(true); + column.addSelectionListener(new ColumnSelectionHandler()); + + // Thread address + column = new TableColumn(tableViewer.getTable(), SWT.RIGHT); + column.setText(Messages.SwiThreadTable_2); + column.setWidth(COLUMN_WIDTH_ADDRESS_COUNT); + column.setData(COLUMN_ID_ADDRESS); + column.setMoveable(true); + column.setResizable(true); + column.addSelectionListener(new ColumnSelectionHandler()); + + // add mouse listener and set other table settings + this.table.addMouseListener(new TableMouseListener()); + this.table.setHeaderVisible(true); + this.table.setLinesVisible(true); + this.table.setRedraw(true); + + // format data into table + this.updateItemData(true); + ((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_SWI_THREAD); + + // Select initially no lines + this.tableViewer.setAllChecked(false); + + // listen for key sequences such as Ctrl-A and Ctrl-C + table.addKeyListener(new TableKeyListener()); + + tableViewer.refresh(); + table.redraw(); + } + + + /** + * Content provider for table + */ + private static class TableContentProvider implements IStructuredContentProvider { + + /** + * Constructor + */ + public TableContentProvider() { + super(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) + */ + @SuppressWarnings("unchecked") + public Object[] getElements(Object inputElement) { + return ((Vector) inputElement).toArray(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#dispose() + */ + public void dispose() { + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object) + */ + public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { + } + } + + /* + * (non-Javadoc) + * @see com.nokia.carbide.cpp.internal.pi.visual.GenericTable#action(java.lang.String) + */ + public void action(String actionString) + { + if (actionString.equals("add")){ //$NON-NLS-1$ + checkOrUncheckSelectedItems(true); + } + else if (actionString.equals("remove")){ //$NON-NLS-1$ + checkOrUncheckSelectedItems(false); + } + else if (actionString.equals("addall")){ //$NON-NLS-1$ + checkOrUncheckAllItems(true); + } + else if (actionString.equals("removeall")){ //$NON-NLS-1$ + checkOrUncheckAllItems(false); + } + else if (actionString.equals("copy")) //$NON-NLS-1$ + { + actionCopyOrSave(true, this.table, CHECKBOX_TEXT, false, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + return; // no redraw needed + } + else if (actionString.equals("copyTable")) //$NON-NLS-1$ + { + actionCopyOrSave(true, this.table, CHECKBOX_TEXT, true, "\t", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + return; // no redraw needed + } + else if (actionString.equals("selectAll")) //$NON-NLS-1$ + { + actionSelectAll(); + return; + } + + else if (actionString.equals("saveTable")) //$NON-NLS-1$ + { + actionCopyOrSave(false, this.table, CHECKBOX_TEXT, true, ",", "\n"); //$NON-NLS-1$ //$NON-NLS-2$ + return; // no redraw needed + } + } + + /** + * Checks or unchecks all selected threads from table + * @param value true if items are checked + */ + private void checkOrUncheckSelectedItems(boolean value) + { + + TableItem[] selectedItems = this.table.getSelection(); + for (int i = 0; i < selectedItems.length; i++) + { + if(selectedItems[i].getData().getClass() == SwiThreadWrapper.class){ + selectedItems[i].setChecked(value); + SwiThreadWrapper wrapper = (SwiThreadWrapper)selectedItems[i].getData(); + if(value){ + myGraph.threadChecked(wrapper.threadName); + } + else{ + myGraph.threadUnchecked(wrapper.threadName); + + } + } + } + myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI); + myGraph.repaint(); + + } + + /** + * Checks or unchecks all table items + * @param value true if all items are checked + */ + private void checkOrUncheckAllItems(boolean value) + { + + TableItem[] allItems = this.table.getItems(); + for (int i = 0; i < allItems.length; i++) + { + if(allItems[i].getData().getClass() == SwiThreadWrapper.class){ + allItems[i].setChecked(value); + SwiThreadWrapper wrapper = (SwiThreadWrapper)allItems[i].getData(); + if(value){ + myGraph.threadChecked(wrapper.threadName); + } + else{ + myGraph.threadUnchecked(wrapper.threadName); + + } + } + + + } + myGraph.repaint(); + myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI); + + } + + /** + * Formats item data into table + * @param setInput true if table needs to be refreshed + */ + public void updateItemData(boolean setInput) + { + tableItemData = ((IrqTrace)this.myGraph.getTrace()).getAllThreadWrappers(); + + // refresh the table, if needed + if (setInput) + refreshTableViewer(); + } + + /** + * Refreshes table viewer + */ + public void refreshTableViewer() + { + this.tableViewer.setInput(tableItemData); + } + + /** + * @return tableviewer of the thread table + */ + public CheckboxTableViewer getTableViewer(){ + return this.tableViewer; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent) + */ + public void checkStateChanged(CheckStateChangedEvent event) { + if(event.getElement().getClass() == SwiThreadWrapper.class){ + SwiThreadWrapper wrapper = (SwiThreadWrapper) event.getElement(); + if(event.getChecked()){ + myGraph.threadChecked(wrapper.threadName); + } + else{ + myGraph.threadUnchecked(wrapper.threadName); + } + myGraph.repaint(); + myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_SWI); + + } + + } + + /** + * Mouse listener of the table + */ + private class TableMouseListener implements MouseListener + { + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDoubleClick(org.eclipse.swt.events.MouseEvent e) { + + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent) + */ + public void mouseDown(org.eclipse.swt.events.MouseEvent e) { + } + + /* + * (non-Javadoc) + * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent) + */ + public void mouseUp(org.eclipse.swt.events.MouseEvent e) { + + if (e.button == MouseEvent.BUTTON3) { + // get rid of last Menu created so we don't have double menu + // on click + if (contextMenu != null) { + contextMenu.dispose(); + } + + contextMenu = new Menu(table.getShell(), SWT.POP_UP); + getCheckRows(contextMenu, table.getSelectionCount() > 0); + + + // select all, copy, and copy all + new MenuItem(contextMenu, SWT.SEPARATOR); + getSelectAllItem(contextMenu, table.getItemCount() > 0); + getCopyItem(contextMenu, table.getSelectionCount() > 0); + getCopyTableItem(contextMenu, table.getItemCount() > 0); + + // save all + new MenuItem(contextMenu, SWT.SEPARATOR); + getSaveTableItem(contextMenu, table.getItemCount() > 0); + + // Recolor highlighted items + new MenuItem(contextMenu, SWT.SEPARATOR); + getRecolorItem(contextMenu, Messages.SwiThreadTable_3, table.getSelectionCount() > 0); + + contextMenu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y)); + contextMenu.setVisible(true); + + table.setMenu(contextMenu); + } + } + } + + /** + * Column selection handler for the table + */ + private class ColumnSelectionHandler extends SelectionAdapter + { + public void widgetSelected(SelectionEvent e) + { + if (!(e.widget instanceof TableColumn)) + return; + + sortOnColumnSelection((TableColumn) e.widget); + } + } + + /** + * @param tableColumn which column is sorted + */ + public void sortOnColumnSelection(TableColumn tableColumn) { + int columnID = ((Integer) tableColumn.getData()).intValue(); + ((SharedSorter) tableViewer.getSorter()).doSort(columnID); + + this.refreshTableViewer(); + this.table.redraw(); + } + + /** + * Sorter for the table + */ + private class SharedSorter extends ViewerSorter { + // last column sorted + private int column = -1; + + /* + * decide on which column to sort by, and the sort ordering + */ + public void doSort(int column) { + // ignore the column passed in and use the id set by the column selection handler + if (column == this.column) { + // sort in other order + sortAscending = !sortAscending; + } else { + // changed columns, so sort in the default order + switch (column) { + case COLUMN_ID_SWI_CHECK: + { + // sort in ascending order + sortAscending = true; + break; + } + case COLUMN_ID_SWI_THREAD: + case COLUMN_ID_ADDRESS: + { + // sort in descending order + sortAscending = false; + break; + } + default: + { + // ignore the column + return; + } + } + this.column = column; + } + + // find the TableColumn corresponding to column, and give it a column direction + TableColumn sortByColumn = null; + for (int i = 0; i < table.getColumnCount(); i++) { + if (table.getColumn(i).getData() instanceof Integer) { + if (((Integer)table.getColumn(i).getData()) == column) { + sortByColumn = table.getColumn(i); + break; + } + } + } + + if (sortByColumn != null) { + table.setSortColumn(sortByColumn); + table.setSortDirection(sortAscending ? SWT.UP : SWT.DOWN); + } + } + + /* + * compare two items from a table column + */ + public int compare(Viewer viewer, Object e1, Object e2) { + int returnCode = 0; + + SwiThreadWrapper elem1 = (SwiThreadWrapper)e1; + SwiThreadWrapper elem2 = (SwiThreadWrapper)e2; + + // find the memory information for the two threads + + // compare based on the memory information + switch (column) { + case COLUMN_ID_SWI_CHECK: + if(tableViewer.getChecked(e1) == true && tableViewer.getChecked(e2) == false){ + returnCode = -1; + } + else{ + returnCode = 1; + } + break; + case COLUMN_ID_SWI_THREAD: + returnCode = elem1.threadName.compareToIgnoreCase(elem2.threadName); + break; + case COLUMN_ID_ADDRESS: + returnCode = elem1.threadAddress > elem2.threadAddress ? 1 : -1; + break; + default: + break; + } + + // for descending order, reverse the sense of the compare + if (!sortAscending) + returnCode = -returnCode; + + return returnCode; + } + } + + + /** + * sets sort direction + * @param sortAscending new sort direction + */ + public void setSortAscending(boolean sortAscending) { + this.sortAscending = sortAscending; + } + +}