com.nokia.carbide.cpp.pi.irq.SwiFunctionTable.java Source code

Java tutorial

Introduction

Here is the source code for com.nokia.carbide.cpp.pi.irq.SwiFunctionTable.java

Source

/*
 * 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.Enumeration;
import java.util.Hashtable;
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.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.ColorDialog;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

import com.nokia.carbide.cpp.internal.pi.visual.GenericTable;

/**
 * Software function interrupt table.
 * 
 */
public class SwiFunctionTable extends GenericTable implements ICheckStateListener {

    // sort direction
    private boolean sortAscending = true;

    /* irq trace graph */
    private IrqTraceGraph myGraph;

    /* parent component where all ui components are placed */
    private Composite parent;

    /* item data for table data */
    protected Vector<IrqSampleTypeWrapper> tableItemData;

    /* function color */
    private Hashtable<String, IrqSampleTypeWrapper> functionColors;

    final boolean checkAllWhenOpened = true;

    /**
     * Constructor
     * 
     * @param myGraph
     *            irq trace graph
     * @param parent
     *            parent component where all ui components are placed
     */
    public SwiFunctionTable(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();
        this.table.setLayoutData(new GridData(GridData.FILL_BOTH));

        // add the check state handler, label provider and content provider
        this.tableViewer.addCheckStateListener(this);
        this.tableViewer.setLabelProvider(new SwiFunctionLabelProvider(this.table));
        this.tableViewer.setContentProvider(new FunctionTableContentProvider());
        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 and color column
        column = new TableColumn(this.table, SWT.CENTER);
        column.setText(Messages.SwiFunctionTable_0);
        column.setWidth(30 + 15);
        column.setData(COLOR_COLUMN_INDEX);
        column.setMoveable(true);
        column.setResizable(true);
        column.addSelectionListener(new ColumnSelectionHandler());

        // Function name column
        column = new TableColumn(this.table, SWT.LEFT);
        column.setText(Messages.SwiFunctionTable_1);
        column.setWidth(COLUMN_WIDTH_SWI_FUNCTION + 15);
        column.setData(COLUMN_ID_SWI_FUNCTION);
        column.setMoveable(true);
        column.setResizable(true);
        column.addSelectionListener(new ColumnSelectionHandler());

        // return address column
        column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
        column.setText(Messages.SwiFunctionTable_2);
        column.setWidth(COLUMN_WIDTH_RETURN_ADDRESS);//  
        column.setData(COLUMN_ID_RETURN_ADDRESS);
        column.setMoveable(true);
        column.setResizable(true);
        column.addSelectionListener(new ColumnSelectionHandler());

        // count column
        column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
        column.setText(Messages.SwiFunctionTable_3);
        column.setWidth(COLUMN_WIDTH_COUNT);
        column.setData(COLUMN_ID_SWI_COUNT);
        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 and sort table
        this.updateItemData(true);
        ((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_SWI_COUNT);

        // initially, all rows are checked
        this.tableViewer.setAllChecked(checkAllWhenOpened);
        this.addColor();

        // listen for key sequences such as Ctrl-A and Ctrl-C
        table.addKeyListener(new TableKeyListener());

        tableViewer.refresh();
        table.redraw();
        this.addColor();

    }

    /**
     * Function table content provider
     */
    private static class FunctionTableContentProvider implements IStructuredContentProvider {
        /**
         * Constructor
         */
        public FunctionTableContentProvider() {
            super();
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.jface.viewers.IStructuredContentProvider#getElements(
         * java.lang.Object)
         */
        @SuppressWarnings("unchecked")
        public Object[] getElements(Object inputElement) {
            return ((Vector<IrqSampleTypeWrapper>) 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) {
        }
    }

    /**
     * updates item data into function table
     * 
     * @param setInput
     *            true if table needs to be refreshed
     */
    public void updateItemData(boolean setInput) {

        // Reset table data
        tableItemData = new Vector<IrqSampleTypeWrapper>();

        functionColors = new Hashtable<String, IrqSampleTypeWrapper>();

        // Get sample type wrappers from trace
        Hashtable<Long, IrqSampleTypeWrapper> sampleTypeWrappers = ((IrqTrace) this.myGraph.getTrace())
                .getSwiTable();
        if (sampleTypeWrappers == null) {
            return;
        }

        // Add sample type wrappers to table data
        Enumeration<Long> k = sampleTypeWrappers.keys();
        while (k.hasMoreElements()) {
            Long key = (Long) k.nextElement();
            if (sampleTypeWrappers.get(key).getClass() == IrqSampleTypeWrapper.class) {
                IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) sampleTypeWrappers.get(key);
                if (wrapper.getPrototypeSample().getFunction() != null) {
                    wrapper.setSelected(checkAllWhenOpened);
                    tableItemData.add(wrapper);
                    functionColors.put(wrapper.getPrototypeSample().getFunction().getFunctionName(), wrapper);
                }

            }
        }

        // refresh the table, if needed
        if (setInput)
            refreshTableViewer();

    }

    /**
     * refreshes table viewer and adds colors into check box column
     */
    public void refreshTableViewer() {
        this.tableViewer.setInput(tableItemData);
        this.addColor();

    }

    /**
     * @return hashtable containing all function colors
     */
    public Hashtable<String, IrqSampleTypeWrapper> getFunctionColors() {
        return functionColors;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse
     * .jface.viewers.CheckStateChangedEvent)
     */
    public void checkStateChanged(CheckStateChangedEvent event) {
        if (event.getElement().getClass() == IrqSampleTypeWrapper.class) {
            IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) event.getElement();
            wrapper.setSelected(event.getChecked());
            myGraph.recalculateWholeGraph();
            myGraph.repaint();
            // myGraph.updateIrqCountsInLegends(IrqTraceGraph.TYPE_SWI);

        }
    }

    /**
     * adds function colors into check box column
     */
    public void addColor() {
        if (this.tableViewer == null)
            return;

        IrqSampleTypeWrapper wrapper;
        TableItem[] items = this.table.getItems();

        for (int i = 0; i < items.length; i++) {
            if (items[i].getData().getClass() == IrqSampleTypeWrapper.class) {
                wrapper = (IrqSampleTypeWrapper) items[i].getData();
                items[i].setBackground(COLOR_COLUMN_INDEX, new Color(parent.getDisplay(), wrapper.rgb));
            }
        }

        table.redraw();
    }

    /*
     * (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(Messages.SwiFunctionTable_4)) {
            actionRecolor();
        } 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() == IrqSampleTypeWrapper.class) {
                selectedItems[i].setChecked(value);
                IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) selectedItems[i].getData();
                wrapper.setSelected(value);
            }
        }
        myGraph.recalculateWholeGraph();
        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() == IrqSampleTypeWrapper.class) {
                allItems[i].setChecked(value);
                IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) allItems[i].getData();
                if (value) {
                    wrapper.setSelected(value);
                } else {
                    wrapper.setSelected(value);

                }
            }

        }
        myGraph.recalculateWholeGraph();
        myGraph.repaint();

    }

    /**
     * Mouselistener for function 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) {
            if (e.button == MouseEvent.BUTTON1) {
                /*
                 * TableItem[] selectedItems = table.getSelection(); if
                 * (selectedItems.length == 0) return;
                 * 
                 * if (selectedItems[0].getData() instanceof MemThread) {
                 * MemThread pMemThread =
                 * (MemThread)(selectedItems[0].getData()); if
                 * (pMemThread.isEnabled(myGraph.getGraphIndex()))
                 * action("remove"); //$NON-NLS-1$ else action("add");
                 * //$NON-NLS-1$ }
                 */
            }
            /*
             * selectAllAction.setEnabled(table.getItemCount() > 0);
             * copyAction.setEnabled(table.getSelectionCount() > 0);
             * copyTableAction.setEnabled(table.getItemCount() > 0);
             */
        }

        /*
         * (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.SwiFunctionTable_5, table.getSelectionCount() > 0);

                contextMenu.setLocation(parent.toDisplay(e.x + table.getLocation().x, e.y + table.getLocation().y));
                contextMenu.setVisible(true);

                table.setMenu(contextMenu);
            }
        }
    }

    /**
     * columnselectionhandler for function table columns
     */
    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 function column
     */
    private class SharedSorter extends ViewerSorter {
        // last column sorted
        private int column = -1;

        /**
         * decide on which column to sort by, and the sort ordering
         * 
         * @param column
         *            which column to sort
         */
        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 COLOR_COLUMN_INDEX: {
                    // sort in ascending order
                    sortAscending = true;
                    break;
                }
                case COLUMN_ID_SWI_FUNCTION:
                case COLUMN_ID_RETURN_ADDRESS:
                case COLUMN_ID_SWI_COUNT: {
                    // 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);
            }
        }

        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.jface.viewers.ViewerComparator#compare(org.eclipse.jface
         * .viewers.Viewer, java.lang.Object, java.lang.Object)
         */
        public int compare(Viewer viewer, Object e1, Object e2) {

            // compare two items from a table column

            int returnCode = 0;

            IrqSampleTypeWrapper elem1 = (IrqSampleTypeWrapper) e1;
            IrqSampleTypeWrapper elem2 = (IrqSampleTypeWrapper) e2;

            // find the information for the two functions

            // compare based on the function information
            switch (column) {

            // color column
            case COLOR_COLUMN_INDEX:
                if (tableViewer.getChecked(e1) == true && tableViewer.getChecked(e2) == false) {
                    returnCode = -1;
                } else {
                    returnCode = 1;
                }
                break;
            // function name column
            case COLUMN_ID_SWI_FUNCTION:
                if (elem1.getPrototypeSample().getFunction() != null
                        && elem2.getPrototypeSample().getFunction() != null) {
                    returnCode = elem1.getPrototypeSample().getFunction().getFunctionName()
                            .compareToIgnoreCase(elem2.getPrototypeSample().getFunction().getFunctionName());
                }
                break;

            // return address column
            case COLUMN_ID_RETURN_ADDRESS:
                if (elem1.getPrototypeSample().getFunction() != null) {
                    returnCode = elem1.getPrototypeSample().getFunction().getStartAddress() > elem2
                            .getPrototypeSample().getFunction().getStartAddress() ? 1 : -1;
                }
                break;

            // interrupt count column
            case COLUMN_ID_SWI_COUNT:
                returnCode = elem1.count > elem2.count ? 1 : -1;
                break;
            default:
                break;
            }

            // for descending order, reverse the sense of the compare
            if (!sortAscending)
                returnCode = -returnCode;

            return returnCode;
        }
    }

    /**
     * Action for opening color dialog for all selected functions.
     */
    private void actionRecolor() {

        // go thru selected items and open color dialog for each.
        TableItem[] selection = table.getSelection();
        for (TableItem item : selection) {

            if (item.getData().getClass() == IrqSampleTypeWrapper.class) {

                IrqSampleTypeWrapper wrapper = (IrqSampleTypeWrapper) item.getData();
                ColorDialog colorDialog = new ColorDialog(this.table.getShell(), SWT.PRIMARY_MODAL);

                // set name of the irq line as topic of the dialog
                colorDialog.setText(IrqSampleTypeWrapper.getLineText(wrapper.getPrototypeSample().getIrqL1Value()));
                RGB color = colorDialog.open();

                // if OK pressed, save new color into trace and set editor as
                // dirty
                if (color != null && color != wrapper.rgb) {

                    // ensure that color is not yet assigned for another
                    // thread/irq line
                    if (!myGraph.getIrqTrace().getColorSet().contains(color)) {
                        myGraph.getIrqTrace().changeColorOfThreadOrIRQLine(wrapper, color);

                    } else {
                        // if same color was alreadyassigned for another
                        // thread/irq line, show error message
                        MessageBox errorDialog = new MessageBox(this.table.getShell(), SWT.ICON_ERROR | SWT.OK);
                        errorDialog.setText(Messages.SwiFunctionTable_6);
                        errorDialog.setMessage(Messages.SwiFunctionTable_7);
                        errorDialog.open();
                    }
                }
            }

        }
        this.myGraph.repaint();
        this.refreshTableViewer();
    }

    /**
     * sets sort direction
     * 
     * @param sortAscending
     *            new sort direction
     */
    public void setSortAscending(boolean sortAscending) {
        this.sortAscending = sortAscending;
    }
}