/* * Copyright (c) 2010-2012 Research In Motion Limited. All rights reserved. * * This program and the accompanying materials are made available * under the terms of the Eclipse Public License, Version 1.0, * which accompanies this distribution and is available at * * http://www.eclipse.org/legal/epl-v10.html * */ package net.rim.ejde.internal.ui.views.profiler; /** * An instance of this class is used to display information of methods included * in given profile data. Information of a method includes information of the * module to which the method belongs, information of the method itself, * information of the source lines of the method, and information of byte code * of the source lines. */ import java.util.Map.Entry; import net.rim.ejde.internal.ui.views.AbstractTreeOwnerDrawLabelProvider; import net.rim.ejde.internal.util.Messages; import net.rim.ide.core.ProfileData; import net.rim.ide.core.ProfileItem; import net.rim.ide.core.ProfileItemSource; import net.rim.ide.core.ProfileLine; import net.rim.ide.core.ProfileMethod; import net.rim.ide.core.ProfileModule; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Event; public class MethodProfileTab extends ProfileTab { private static final int PROFILE_MODULE = 0; private static final int PROFILE_METHOD = 1; private static final int UNRECOGINZED_TYPE = -1; AllMethods _allMethods; /** * Constructs an instance of MethodProfileTab * * @param view * An instance of ProfileView on which this tab will be displayed. */ public MethodProfileTab( ProfilerView view ) { super( view ); getTabItem().setText( Messages.MethodProfileTab_METHOD_TAB_TITLE ); _displayLevelofTab = PROFILE_METHOD_LEVEL; } /** * Initializes the tab. */ void initializeTableViewer() { // call super's method super.initializeTableViewer(); _columns[ COLUM_PERCENT ].addSelectionListener( new SelectionListener() { public void widgetDefaultSelected( SelectionEvent e ) { // nothing to do } public void widgetSelected( SelectionEvent e ) { setComparator( _ticksComparator ); } } ); _columns[ COLUM_TICKS ].addSelectionListener( new SelectionListener() { public void widgetDefaultSelected( SelectionEvent e ) { // nothing to do } public void widgetSelected( SelectionEvent e ) { setComparator( _ticksComparator ); } } ); _columns[ COLUM_COUNT ].addSelectionListener( new SelectionListener() { public void widgetDefaultSelected( SelectionEvent e ) { // nothing to do } public void widgetSelected( SelectionEvent e ) { setComparator( _countComparator ); } } ); _tableViewer.getTable().addMouseListener( new MyMouseAdapter() ); } /** * Checks if <code>item</code> was expanded. * * @param item * @return */ protected boolean isItemExpanded( Object item ) { if( item instanceof ProfileItem ) return _expansions.get( ( (ProfileItem) item ).getHandle() ) != null; else if( item instanceof AllMethods ) return _expansions.get( ( (AllMethods) item ).getLabel() ) != null; return false; } public int getIndent( Object obj ) { if( ProfileTab.getDisplayLevel( obj ) < _displayLevelofTab ) return UNRECOGINZED_TYPE; if( obj instanceof ProfileModule ) return PROFILE_MODULE; if( obj instanceof AllMethods ) return PROFILE_MODULE; else if( obj instanceof ProfileMethod ) return PROFILE_METHOD; else return UNRECOGINZED_TYPE; } Object[] getChildren( Object obj ) { if( obj instanceof ProfileItem ) return ( (ProfileItem) obj ).sortedChildren( _comparator ); else if( obj instanceof AllMethods ) return ( (AllMethods) obj ).getChildren(); return new Object[ 0 ]; } int getChildrenCount( Object obj ) { if( obj instanceof ProfileItem ) return ( (ProfileItem) obj ).getChildCount(); else if( obj instanceof AllMethods ) return ( (AllMethods) obj ).getChildren().length; return 0; } /** * @see ProfileTab#displayData(ProfileItemSource pis). * * @param pis * An instance of ProfileData. */ void displayData( ProfileItemSource pis ) { if( !( pis instanceof ProfileData ) ) return; ProfileData pd = (ProfileData) pis; setTotal( pd.getTotalExecutionTicks() ); // set pd as input and its data will be automatically displayed // on the tree Object[] children = pd.sortedChildren( _comparator ); _data = new Object[ children.length + 1 ]; System.arraycopy( children, 0, _data, 1, children.length ); _allMethods = new AllMethods( pd ); _data[ 0 ] = _allMethods; _data = handleExpandedItems( _data ); displayData( _data ); } Object[] handleExpandedItems( Object[] data ) { if( data == null ) return new Object[ 0 ]; Object[] newData = data; for( int i = PROFILE_MODULE; i <= PROFILE_METHOD; i++ ) { for( Object object : _expansions.entrySet() ) { Object value = ( (Entry) object ).getValue(); if( getIndent( value ) == i ) newData = expandItem( newData, value ); } } return newData; } /** * @see ProfileTab#createLabelProvider() */ AbstractTreeOwnerDrawLabelProvider createLabelProvider() { AbstractTreeOwnerDrawLabelProvider provider = new MyLabelProvider( this ); provider.setDiaplsyLevel( PROFILE_METHOD_LEVEL ); return provider; } class MyLabelProvider extends AbstractProfileLabelProvider { public MyLabelProvider( ProfileTab tab ) { super( tab ); } /* * (non-Javadoc) * * @see org.eclipse.jface.viewers.OwnerDrawLabelProvider#paint(org.eclipse .swt.widgets.Event, java.lang.Object) */ protected void paint( Event event, Object element ) { // call super method to initiate variables super.paint( event, element ); String text = EMPTY_STRING; if( element instanceof ProfileItem ) { // if the element is a ProfileItem, get value of each column ProfileItem pi = (ProfileItem) element; long ticks = pi.getTicks(); switch( event.index ) { case COLUM_DETAIL: { if( pi instanceof ProfileLine ) // display source line text = (String) ( (ProfileLine) pi ).getLineHandle().getLine(); else text = pi.toString(); break; } case COLUM_PERCENT: { text = getPercent( ticks ); break; } case COLUM_TICKS: { text = String.valueOf( ticks ); break; } case COLUM_COUNT: { text = String.valueOf( pi.getCount() ); break; } default: text = EMPTY_STRING; } } else if( element instanceof AllMethods ) text = ( (AllMethods) element ).getLabel(); if( event.index == 0 ) drawFirstColumn( event, element, text, false ); else drawText( event, text, event.x, event.y, false ); } } class MyMouseAdapter extends MouseAdapter { /** * When a TableItem which presents a ProfileLine instance is double clicked, the source file will be opened in an editor. */ public void mouseDoubleClick( MouseEvent e ) { // Get selected TableItem int index = _tableViewer.getTable().getSelectionIndex(); if( index < 0 ) // if nothing selected, return return; // its a single-select tree Object obj = _tableViewer.getTable().getItem( index ).getData(); if( obj instanceof ProfileMethod ) { // if selected TableItem present a ProfileMethod instance // display the source code of the ProfileMethod. _profilerView.displaySourceData( (ProfileItem) obj ); } } } }