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

Java tutorial

Introduction

Here is the source code for com.nokia.carbide.cpp.pi.irq.IrqLineTable.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.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;

/**
 * Table for irq lines
 */
public class IrqLineTable extends GenericTable implements ICheckStateListener {

    /* sort direction */
    private boolean sortAscending = true;

    /* Graph */
    private IrqTraceGraph myGraph;

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

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

    /**
     * Constructor
     * 
     * @param myGraph
     *            graph
     * @param parent
     *            Parent component where ui components are placed
     */
    public IrqLineTable(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 IrqLineLabelProvider(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 and color column
        column = new TableColumn(this.table, SWT.CENTER);
        column.setText(Messages.IrqLineTable_0);
        column.setWidth(COLUMN_WIDTH_CHECK_COLUMN);
        column.setData(COLOR_COLUMN_INDEX);
        column.setMoveable(true);
        column.setResizable(true);
        column.addSelectionListener(new ColumnSelectionHandler());

        // Thread line column
        column = new TableColumn(this.table, SWT.LEFT);
        column.setText(Messages.IrqLineTable_1);
        column.setWidth(COLUMN_WIDTH_THREAD_IRQ_LINE);
        column.setData(COLUMN_ID_IRQ_LINE);
        column.setMoveable(true);
        column.setResizable(true);
        column.addSelectionListener(new ColumnSelectionHandler());

        // Return address
        column = new TableColumn(tableViewer.getTable(), SWT.RIGHT);
        column.setText(Messages.IrqLineTable_2);
        column.setWidth(COLUMN_WIDTH_ADDRESS_COUNT);
        column.setData(COLUMN_ID_IRQ_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
        this.updateItemData(true);
        ((SharedSorter) tableViewer.getSorter()).doSort(COLUMN_ID_IRQ_COUNT);

        // 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();
        this.addColor();
    }

    /**
     * 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<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) {
        }
    }

    /*
     * (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.IrqLineTable_3)) {
            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 irq lines from table
     * 
     * @param value
     *            true if items are checked
     */
    private void checkOrUncheckSelectedItems(boolean value) {
        // go thru selected items from thread table and notify graph that
        // threads are checked or unchecked
        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();
                if (value) {
                    myGraph.irqLineChecked(wrapper);
                } else {
                    myGraph.irqLineUnchecked(wrapper);

                }
            }

        }
        myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);
        myGraph.repaint();

    }

    /**
     * Checks or unchecks all table items
     * 
     * @param value
     *            true if all items are checked
     */
    private void checkOrUncheckAllItems(boolean value) {
        // go thru all items from thread table and notify graph that threads are
        // checked or unchecked
        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) {
                    myGraph.irqLineChecked(wrapper);
                } else {
                    myGraph.irqLineUnchecked(wrapper);

                }
            }

        }
        myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);
        myGraph.repaint();

    }

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

        // get sample type wrappers from irq trace
        tableItemData = new Vector<IrqSampleTypeWrapper>();
        Hashtable<Long, IrqSampleTypeWrapper> irqLines = this.myGraph.getIrqTrace().getIrqTable();

        // create table item for each sample type wrapper
        Enumeration<Long> k = irqLines.keys();
        while (k.hasMoreElements()) {
            IrqSampleTypeWrapper threadValue = (IrqSampleTypeWrapper) irqLines.get(k.nextElement());
            tableItemData.add(threadValue);
        }

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

    /**
     * Refreshes table viewer
     */
    public void refreshTableViewer() {
        this.tableViewer.setInput(tableItemData);
        this.addColor();

    }

    /**
     * @return table viewer
     */
    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() == IrqSampleTypeWrapper.class) {
            IrqSampleTypeWrapper irqLine = (IrqSampleTypeWrapper) event.getElement();
            if (event.getChecked()) {
                myGraph.irqLineChecked(irqLine);
            } else {
                myGraph.irqLineUnchecked(irqLine);
            }
            myGraph.repaint();
            myGraph.updateIrqCountsInLegendsAsynch(IrqTraceGraph.TYPE_IRQ);

        }
    }

    /**
     * Adds colors into irq line table
     */
    public void addColor() {
        if (this.tableViewer == null)
            return;

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

        table.redraw();
    }

    /**
     * MouseListener for 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.IrqLineTable_4, 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 irq columns
     */
    private class ColumnSelectionHandler extends SelectionAdapter {
        /*
         * (non-Javadoc)
         * 
         * @see
         * org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse
         * .swt.events.SelectionEvent)
         */
        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 irq 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 COLOR_COLUMN_INDEX: {
                    // sort in ascending order
                    sortAscending = true;
                    break;
                }
                case COLUMN_ID_IRQ_LINE:
                case COLUMN_ID_IRQ_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);
            }
        }

        /*
         * compare two items from a table column
         */
        public int compare(Viewer viewer, Object e1, Object e2) {
            int returnCode = 0;

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

            // find the information for the two irq lines

            // compare based on the memory information
            switch (column) {
            case COLOR_COLUMN_INDEX:
                if (tableViewer.getChecked(e1) == true && tableViewer.getChecked(e2) == false) {
                    returnCode = -1;
                } else {
                    returnCode = 1;
                }
                break;
            case COLUMN_ID_IRQ_LINE:
                returnCode = elem1.getPrototypeSample().getIrqL1Value() > elem2.getPrototypeSample().getIrqL1Value()
                        ? 1
                        : -1;
                break;
            case COLUMN_ID_IRQ_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 irq lines.
     */
    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.IrqLineTable_5);
                        errorDialog.setMessage(Messages.IrqLineTable_6);
                        errorDialog.open();
                    }
                }

            }

        }
        this.myGraph.repaint();
        myGraph.getIrqTrace().updateAllTableViewers();
    }

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

}