Java tutorial
/******************************************************************************* * Copyright (c) 2009 Red Hat, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Elliott Baron <ebaron@redhat.com> - initial API and implementation *******************************************************************************/ package org.eclipse.linuxtools.internal.valgrind.cachegrind; import java.util.Arrays; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.ISourceRange; import org.eclipse.cdt.core.model.ISourceReference; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.TreeViewerColumn; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.linuxtools.internal.valgrind.cachegrind.model.CachegrindFile; import org.eclipse.linuxtools.internal.valgrind.cachegrind.model.CachegrindFunction; import org.eclipse.linuxtools.internal.valgrind.cachegrind.model.CachegrindLine; import org.eclipse.linuxtools.internal.valgrind.cachegrind.model.CachegrindOutput; import org.eclipse.linuxtools.internal.valgrind.cachegrind.model.ICachegrindElement; import org.eclipse.linuxtools.profiling.ui.ProfileUIUtils; import org.eclipse.linuxtools.valgrind.ui.IValgrindToolView; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; import org.eclipse.ui.PartInitException; import org.eclipse.ui.part.ViewPart; public class CachegrindViewPart extends ViewPart implements IValgrindToolView { protected CachegrindOutput[] outputs; protected TreeViewer viewer; protected static final int COLUMN_SIZE = 75; protected CachegrindLabelProvider labelProvider; protected CachegrindTreeContentProvider contentProvider; protected IDoubleClickListener doubleClickListener; protected ExpandAction expandAction; protected CollapseAction collapseAction; // Events - Cache protected static final String IR = "Ir"; //$NON-NLS-1$ protected static final String I1MR = "I1mr"; //$NON-NLS-1$ protected static final String I2MR = "I2mr"; //$NON-NLS-1$ protected static final String DR = "Dr"; //$NON-NLS-1$ protected static final String D1MR = "D1mr"; //$NON-NLS-1$ protected static final String D2MR = "D2mr"; //$NON-NLS-1$ protected static final String DW = "Dw"; //$NON-NLS-1$ protected static final String D1MW = "D1mw"; //$NON-NLS-1$ protected static final String D2MW = "D2mw"; //$NON-NLS-1$ // Events - Branch protected static final String BC = "Bc"; //$NON-NLS-1$ protected static final String BCM = "Bcm"; //$NON-NLS-1$ protected static final String BI = "Bi"; //$NON-NLS-1$ protected static final String BIM = "Bim"; //$NON-NLS-1$ @Override public void createPartControl(Composite parent) { Composite top = new Composite(parent, SWT.NONE); GridLayout topLayout = new GridLayout(); topLayout.marginHeight = topLayout.marginWidth = 0; top.setLayout(topLayout); top.setLayoutData(new GridData(GridData.FILL_BOTH)); viewer = new TreeViewer(top, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); labelProvider = new CachegrindLabelProvider(); Tree tree = viewer.getTree(); tree.setHeaderVisible(true); tree.setLinesVisible(true); tree.setLayoutData(new GridData(GridData.FILL_BOTH)); TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.NONE); column.getColumn().setText(Messages.getString("CachegrindViewPart.Location")); //$NON-NLS-1$ column.getColumn().setWidth(COLUMN_SIZE * 4); column.getColumn().setResizable(true); column.getColumn().addSelectionListener(getHeaderListener()); column.setLabelProvider(labelProvider); contentProvider = new CachegrindTreeContentProvider(); viewer.setContentProvider(contentProvider); viewer.setLabelProvider(labelProvider); viewer.setAutoExpandLevel(2); doubleClickListener = new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { Object selection = ((StructuredSelection) event.getSelection()).getFirstElement(); String path = null; int line = 0; if (selection instanceof CachegrindFile) { path = ((CachegrindFile) selection).getPath(); } else if (selection instanceof CachegrindLine) { CachegrindLine element = (CachegrindLine) selection; CachegrindFile file = (CachegrindFile) element.getParent().getParent(); path = file.getPath(); line = element.getLine(); } else if (selection instanceof CachegrindFunction) { CachegrindFunction function = (CachegrindFunction) selection; path = ((CachegrindFile) function.getParent()).getPath(); if (function.getModel() instanceof ISourceReference) { ISourceReference model = (ISourceReference) function.getModel(); try { ISourceRange sr = model.getSourceRange(); if (sr != null) { line = sr.getStartLine(); } } catch (CModelException e) { e.printStackTrace(); } } } if (path != null) { try { ProfileUIUtils.openEditorAndSelect(path, line); } catch (PartInitException e) { e.printStackTrace(); } catch (BadLocationException e) { e.printStackTrace(); } } } }; viewer.addDoubleClickListener(doubleClickListener); expandAction = new ExpandAction(viewer); collapseAction = new CollapseAction(viewer); MenuManager manager = new MenuManager(); manager.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { ITreeSelection selection = (ITreeSelection) viewer.getSelection(); ICachegrindElement element = (ICachegrindElement) selection.getFirstElement(); if (contentProvider.hasChildren(element)) { manager.add(expandAction); manager.add(collapseAction); } } }); manager.setRemoveAllWhenShown(true); Menu contextMenu = manager.createContextMenu(viewer.getTree()); viewer.getControl().setMenu(contextMenu); } @Override public void setFocus() { viewer.getTree().setFocus(); } public IAction[] getToolbarActions() { return null; } public void refreshView() { if (outputs != null && outputs.length > 0) { String[] events = outputs[0].getEvents(); for (int i = 0; i < events.length; i++) { TreeViewerColumn column = new TreeViewerColumn(viewer, SWT.NONE); column.getColumn().setText(events[i]); column.getColumn().setWidth(COLUMN_SIZE); column.getColumn().setToolTipText(getFullEventName(events[i])); column.getColumn().setResizable(true); column.getColumn().addSelectionListener(getHeaderListener()); column.setLabelProvider(labelProvider); } viewer.setInput(outputs); viewer.getTree().layout(true); } } public void setOutputs(CachegrindOutput[] outputs) { this.outputs = outputs; } public CachegrindOutput[] getOutputs() { return outputs; } public TreeViewer getViewer() { return viewer; } public IDoubleClickListener getDoubleClickListener() { return doubleClickListener; } private SelectionListener getHeaderListener() { return new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { TreeColumn column = (TreeColumn) e.widget; Tree tree = viewer.getTree(); if (column.equals(tree.getSortColumn())) { int direction = tree.getSortDirection() == SWT.UP ? SWT.DOWN : SWT.UP; tree.setSortDirection(direction); } else { tree.setSortDirection(SWT.UP); } tree.setSortColumn(column); viewer.setComparator(new ViewerComparator() { @Override public int compare(Viewer viewer, Object e1, Object e2) { Tree tree = ((TreeViewer) viewer).getTree(); int direction = tree.getSortDirection(); ICachegrindElement o1 = (ICachegrindElement) e1; ICachegrindElement o2 = (ICachegrindElement) e2; long result = 0; int sortIndex = Arrays.asList(tree.getColumns()).indexOf(tree.getSortColumn()); if (sortIndex == 0) { // use compareTo result = o1.compareTo(o2); } else { long[] v1 = null; long[] v2 = null; if (o1 instanceof CachegrindFunction && o2 instanceof CachegrindFunction) { v1 = ((CachegrindFunction) o1).getTotals(); v2 = ((CachegrindFunction) o2).getTotals(); } else if (o1 instanceof CachegrindLine && o2 instanceof CachegrindLine) { v1 = ((CachegrindLine) o1).getValues(); v2 = ((CachegrindLine) o2).getValues(); } else if (o1 instanceof CachegrindOutput && o2 instanceof CachegrindOutput) { v1 = ((CachegrindOutput) o1).getSummary(); v2 = ((CachegrindOutput) o2).getSummary(); } if (v1 != null && v2 != null) { result = v1[sortIndex - 1] - v2[sortIndex - 1]; } } // ascending or descending result = direction == SWT.UP ? result : -result; // overflow check if (result > Integer.MAX_VALUE) { result = Integer.MAX_VALUE; } else if (result < Integer.MIN_VALUE) { result = Integer.MIN_VALUE; } return (int) result; } }); } }; } private String getFullEventName(String event) { String result = event; if (event.equals(IR)) { result = Messages.getString("CachegrindViewPart.Ir_long"); //$NON-NLS-1$ } else if (event.equals(I1MR)) { result = Messages.getString("CachegrindViewPart.I1mr_long"); //$NON-NLS-1$ } else if (event.equals(I2MR)) { result = Messages.getString("CachegrindViewPart.I2mr_long"); //$NON-NLS-1$ } else if (event.equals(DR)) { result = Messages.getString("CachegrindViewPart.Dr_long"); //$NON-NLS-1$ } else if (event.equals(D1MR)) { result = Messages.getString("CachegrindViewPart.D1mr_long"); //$NON-NLS-1$ } else if (event.equals(D2MR)) { result = Messages.getString("CachegrindViewPart.D2mr_long"); //$NON-NLS-1$ } else if (event.equals(DW)) { result = Messages.getString("CachegrindViewPart.Dw_long"); //$NON-NLS-1$ } else if (event.equals(D1MW)) { result = Messages.getString("CachegrindViewPart.D1mw_long"); //$NON-NLS-1$ } else if (event.equals(D2MW)) { result = Messages.getString("CachegrindViewPart.D2mw_long"); //$NON-NLS-1$ } else if (event.equals(BC)) { result = Messages.getString("CachegrindViewPart.Bc_long"); //$NON-NLS-1$ } else if (event.equals(BCM)) { result = Messages.getString("CachegrindViewPart.Bcm_long"); //$NON-NLS-1$ } else if (event.equals(BI)) { result = Messages.getString("CachegrindViewPart.Bi_long"); //$NON-NLS-1$ } else if (event.equals(BIM)) { result = Messages.getString("CachegrindViewPart.Bim_long"); //$NON-NLS-1$ } return result; } protected class CachegrindTreeContentProvider implements ITreeContentProvider { public Object[] getChildren(Object parentElement) { Object[] result = null; if (parentElement instanceof CachegrindOutput[]) { result = (CachegrindOutput[]) parentElement; } else if (parentElement instanceof ICachegrindElement) { result = ((ICachegrindElement) parentElement).getChildren(); } return result; } public Object getParent(Object element) { return ((ICachegrindElement) element).getParent(); } public boolean hasChildren(Object element) { ICachegrindElement[] children = (ICachegrindElement[]) getChildren(element); return children != null && children.length > 0; } public Object[] getElements(Object inputElement) { return getChildren(inputElement); } public void dispose() { } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { } } }