--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTraceGraph.java Thu Feb 11 15:32:31 2010 +0200
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2009 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.button;
+
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.Vector;
+
+import org.eclipse.draw2d.ColorConstants;
+import org.eclipse.draw2d.FigureCanvas;
+import org.eclipse.draw2d.Graphics;
+import org.eclipse.draw2d.Panel;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.MouseMoveListener;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Shell;
+
+import com.nokia.carbide.cpp.internal.pi.actions.SaveSamples;
+import com.nokia.carbide.cpp.internal.pi.analyser.NpiInstanceRepository;
+import com.nokia.carbide.cpp.internal.pi.interfaces.ISaveSamples;
+import com.nokia.carbide.cpp.internal.pi.model.GenericSampledTrace;
+import com.nokia.carbide.cpp.internal.pi.plugin.model.IContextMenu;
+import com.nokia.carbide.cpp.internal.pi.visual.GenericTraceGraph;
+import com.nokia.carbide.cpp.pi.editors.PIPageEditor;
+
+
+public class BupTraceGraph extends GenericTraceGraph implements MouseMoveListener,
+ MouseListener,
+ IContextMenu
+{
+ /*
+ * Draw button text in existing Address plugin panel
+ *
+ * For each button press, draw a line from the top to below the thread/binary/function start and end
+ * indicators, but above the x-axis label that tells seconds
+ */
+
+ // whether to display events
+ private boolean display_events = true;
+
+ // constants used in drawing event: line coming down with a rectangle at the end and a name underneath
+ private static final int EVENT_TOPOFLINE = 50;
+ private static final int EVENT_BOTTOMOFLINE = 30;
+ private static final int EVENT_RECTWIDTH = 5;
+ private static final int EVENT_RECTHEIGHT = 5;
+
+ private ArrayList<BupSample> matchingSamples;
+ private Button eventButtons[];
+ private boolean selectedEventButtons;
+
+ // class to pass sample data to the save wizard
+ public class SaveSampleString implements ISaveSamples {
+ boolean done = false;
+
+ public SaveSampleString() {
+ }
+
+ public String getData() {
+ if (done)
+ return null;
+
+ String returnString = getSampleString();
+ done = true;
+ return returnString;
+ }
+
+ public String getData(int size) {
+ return getData();
+ }
+
+ public int getIndex() {
+ return done ? 1 : 0;
+ }
+
+ public void clear() {
+ done = false;
+ }
+ }
+
+ /*
+ * return the button samples selected in the interval
+ */
+ protected String getSampleString()
+ {
+ int startTime = (int) this.getSelectionStart();
+ int endTime = (int) this.getSelectionEnd();
+
+ Vector sampleVector = ((GenericSampledTrace) this.getTrace()).samples;
+
+ int i = 0;
+ while (i < sampleVector.size() && ((BupSample) sampleVector.get(i)).sampleSynchTime < startTime)
+ i++;
+
+ String returnString = Messages.getString("BupTraceGraph.saveSamplesHeading"); //$NON-NLS-1$
+
+ while (i < sampleVector.size() && ((BupSample) sampleVector.get(i)).sampleSynchTime <= endTime) {
+ BupSample sample = (BupSample) sampleVector.get(i);
+ returnString += sample.sampleSynchTime + "," + sample.getLabel() + ",\""; //$NON-NLS-1$ //$NON-NLS-2$
+
+ String comment = sample.getComment();
+ if (comment != null) {
+ for (int j = 0; j < comment.length(); j++) {
+ if (comment.charAt(j) == '"')
+ returnString += '"';
+ returnString += comment.charAt(j);
+ }
+ }
+ returnString += "\"\n"; //$NON-NLS-1$
+ i++;
+ }
+
+ return returnString;
+ }
+
+ protected void actionSaveSamples(ISaveSamples saveSamples)
+ {
+ new SaveSamples(saveSamples);
+ }
+
+ protected MenuItem getSaveSamplesItem(Menu menu, boolean enabled) {
+ MenuItem saveSamplesItem = new MenuItem(menu, SWT.PUSH);
+
+ saveSamplesItem.setText(Messages.getString("BupTraceGraph.saveSamplesForInterval")); //$NON-NLS-1$
+ saveSamplesItem.setEnabled(enabled);
+
+ if (enabled) {
+ saveSamplesItem.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ saveEventSamples();
+ }
+ });
+ }
+
+ return saveSamplesItem;
+ }
+
+ public BupTraceGraph(int graphIndex, BupTrace trace)
+ {
+ super(trace);
+ this.graphIndex = graphIndex;
+ }
+
+ public void paint(Panel panel, Graphics graphics)
+ {
+ if (!display_events)
+ return;
+
+ Enumeration samples = ((GenericSampledTrace)this.getTrace()).samples.elements();
+ graphics.setForegroundColor(ColorConstants.red);
+ double scale = this.getScale();
+ int height = this.getVisualSize().height;
+ String eventName;
+
+ while (samples.hasMoreElements())
+ {
+ BupSample sa = (BupSample)samples.nextElement();
+ int x = (int)(sa.sampleSynchTime/scale);
+
+ graphics.setForegroundColor(ColorConstants.red);
+ graphics.drawLine(x, height - EVENT_TOPOFLINE, x, height - EVENT_BOTTOMOFLINE);
+
+ // center the text under vertical line
+ eventName = sa.getLabel();
+
+ graphics.setFont(PIPageEditor.helvetica_8);
+
+ GC gc = new GC(PIPageEditor.currentPageEditor().getSite().getShell());
+ Point point = gc.stringExtent(eventName);
+ gc.dispose();
+
+ if (sa.isLabelModified()) {
+ graphics.setForegroundColor(ColorConstants.blue);
+ } else {
+ graphics.setForegroundColor(ColorConstants.red);
+ }
+ graphics.drawString(eventName, x - (point.x / 2), height - EVENT_BOTTOMOFLINE + 3 + EVENT_RECTHEIGHT);
+
+ // events with comments will have blue rectangles; otherwise, red triangles
+ if ((sa.getComment() != null) && (!sa.getComment().equals(""))) //$NON-NLS-1$
+ {
+ graphics.setForegroundColor(ColorConstants.blue);
+ graphics.setBackgroundColor(ColorConstants.blue);
+ }
+ else
+ {
+ graphics.setBackgroundColor(ColorConstants.red);
+ }
+ graphics.drawLine(x , height - EVENT_BOTTOMOFLINE + 1, x, height - EVENT_BOTTOMOFLINE + 2);
+ graphics.fillRectangle(x - (EVENT_RECTWIDTH / 2), height - EVENT_BOTTOMOFLINE + 3,
+ EVENT_RECTWIDTH, EVENT_RECTHEIGHT);
+ }
+ }
+
+ public void repaint()
+ {
+ }
+
+ public void refreshDataFromTrace()
+ {
+ }
+
+ public void action(String action)
+ {
+ // do/don't show events in graph
+ if ( action.equals("button_events_on") //$NON-NLS-1$
+ || action.equals("button_events_off")) //$NON-NLS-1$
+ {
+ this.display_events = action.equals(Messages.getString("BupTraceGraph.button.events.on")); //$NON-NLS-1$
+ this.parentComponent.repaintComponent();
+ } else if (action.equals("button_map_switch")){ //$NON-NLS-1$
+ this.parentComponent.repaintComponent();
+ }
+ }
+
+ public void mouseMove(MouseEvent me)
+// public void mouseHover(MouseEvent me)
+ {
+ if (!display_events)
+ return;
+
+ long x = me.x;
+ long y = me.y;
+
+ int height = this.getVisualSize().height;
+
+ // make sure we're in the right area of the graph window
+ if ((y < height - EVENT_BOTTOMOFLINE) || (y > height - EVENT_BOTTOMOFLINE + EVENT_RECTHEIGHT + 2))
+ return;
+
+ Enumeration samples = ((GenericSampledTrace) this.getTrace()).samples.elements();
+ double scale = this.getScale();
+
+// x += ((FigureCanvas)me.getSource()).getViewport().getViewLocation().x;
+
+ String tooltip = ""; //$NON-NLS-1$
+
+ while (samples.hasMoreElements())
+ {
+ BupSample sample = (BupSample)samples.nextElement();
+ long xSample = (long)(sample.sampleSynchTime/scale + 0.5);
+
+ // samples are in timestamp order, so stop when xSample + EVENT_RECTWIDTH is too high
+ if (x < xSample - EVENT_RECTWIDTH)
+ break;
+
+ if ((x >= xSample - EVENT_RECTWIDTH) && (x <= xSample + EVENT_RECTWIDTH))
+ {
+ String parsedName = sample.getLabel();
+ if (!tooltip.equals("")) //$NON-NLS-1$
+ tooltip += Messages.getString("BupTraceGraph.newline"); //$NON-NLS-1$
+ tooltip += Messages.getString("BupTraceGraph.tooltip1") + parsedName + Messages.getString("BupTraceGraph.tooltip2") + sample.sampleSynchTime/1000.0 + Messages.getString("BupTraceGraph.tooltip3"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ if (sample.getComment() != null)
+ tooltip += Messages.getString("BupTraceGraph.tooltip4") + sample.getComment(); //$NON-NLS-1$
+ }
+ }
+
+ if (!tooltip.equals("")) //$NON-NLS-1$
+ ((FigureCanvas)me.getSource()).setToolTipText(tooltip);
+ }
+
+ public void mouseDoubleClick(MouseEvent me)
+ {
+ if (!display_events)
+ return;
+
+ long x = me.x;
+ long y = me.y;
+
+ int height = this.getVisualSize().height;
+
+ // make sure we're in the right area of the graph window
+ if ((y < height - EVENT_BOTTOMOFLINE) || (y > height - EVENT_BOTTOMOFLINE + EVENT_RECTHEIGHT + 2))
+ return;
+
+ // repaint if the name or comment changes
+ boolean redraw = false;
+
+ Enumeration samples = ((GenericSampledTrace)this.getTrace()).samples.elements();
+ double scale = this.getScale();
+
+ // unlike mouseMove, the x coordinate is not relative to the FigureCanvas
+ x += ((FigureCanvas)me.getSource()).getViewport().getViewLocation().x;
+
+ matchingSamples = new ArrayList<BupSample>();
+
+ while (samples.hasMoreElements())
+ {
+ BupSample sample = (BupSample)samples.nextElement();
+ long xSample = (long)(sample.sampleSynchTime/scale + 0.5);
+
+ // samples are in timestamp order, so stop when xSample + EVENT_RECTWIDTH is too high
+ if (x < xSample - EVENT_RECTWIDTH)
+ break;
+
+ if ((x >= xSample - EVENT_RECTWIDTH) && (x <= xSample + EVENT_RECTWIDTH))
+ {
+ matchingSamples.add(sample);
+ }
+ }
+
+ if (matchingSamples.size() == 0)
+ return;
+
+ // let them change some information
+ Display display = PIPageEditor.currentPageEditor().getEditorSite().getShell().getDisplay();
+
+ GridData gridData;
+
+ if (matchingSamples.size() > 1) {
+ selectedEventButtons = false;
+
+ // query for which of several to display
+ Shell shell = new Shell(display, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
+ shell.setText(Messages.getString("BupTraceGraph.chooseEvents")); //$NON-NLS-1$
+ shell.setLayout(new GridLayout(2, true));
+ final Shell shellFinal = shell;
+
+ Label label = new Label(shell, SWT.LEFT);
+ label.setText(Messages.getString("BupTraceGraph.selectEvents")); //$NON-NLS-1$
+ label.setFont(PIPageEditor.helvetica_10);
+ gridData = new GridData(GridData.FILL_HORIZONTAL);
+ gridData.horizontalSpan = 2;
+ label.setLayoutData(gridData);
+
+ eventButtons = new Button[matchingSamples.size()];
+
+ for (int i = 0; i < matchingSamples.size(); i++) {
+ eventButtons[i] = new Button(shell, SWT.CHECK);
+ gridData = new GridData(GridData.FILL_HORIZONTAL);
+ gridData.horizontalSpan = 2;
+ eventButtons[i].setLayoutData(gridData);
+
+ BupSample sample = matchingSamples.get(i);
+
+ String parsedName = sample.getLabel();
+ eventButtons[i].setText(Messages.getString("BupTraceGraph.buttonString1") + parsedName + Messages.getString("BupTraceGraph.buttonString2") + sample.sampleSynchTime/1000d + Messages.getString("BupTraceGraph.buttonString3")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ eventButtons[i].setFont(PIPageEditor.helvetica_10);
+ }
+
+ // create the OK button
+ Button okButton = new Button(shell, SWT.NONE);
+ okButton.setText(Messages.getString("BupTraceGraph.ok")); //$NON-NLS-1$
+ gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ okButton.setLayoutData(gridData);
+
+ // add the listener(s)
+ okButton.addSelectionListener(new SelectionListener(){
+ public void widgetSelected(SelectionEvent e) {
+ selectedEventButtons = true;
+ for (int i = matchingSamples.size() - 1; i >= 0; i--)
+ if (eventButtons[i].getSelection() == false)
+ matchingSamples.remove(i);
+
+ shellFinal.close();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ // create the Cancel button
+ Button cancelButton = new Button(shell, SWT.NONE);
+ cancelButton.setText(Messages.getString("BupTraceGraph.cancel")); //$NON-NLS-1$
+ gridData = new GridData(GridData.HORIZONTAL_ALIGN_CENTER);
+ cancelButton.setLayoutData(gridData);
+
+ // add the listener(s)
+ cancelButton.addSelectionListener(new SelectionListener(){
+ public void widgetSelected(SelectionEvent e) {
+ shellFinal.close();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ widgetSelected(e);
+ }
+ });
+
+ shell.pack();
+ shell.open();
+
+ while (!shell.isDisposed()) {
+ if (!display.readAndDispatch()) {
+ display.sleep();
+ }
+ }
+
+ if (selectedEventButtons == false)
+ matchingSamples.clear();
+ }
+
+ IBupEventMap map = ((BupTrace)this.getTrace()).getCurrentBupMapInUse();
+ for (int i = 0; i < matchingSamples.size(); i++)
+ {
+ BupSample sample = matchingSamples.get(i);
+
+ String enumString = map.getEnum(sample.getKeyCode());
+
+ BupEventDialog eventDialog = new BupEventDialog(PIPageEditor.currentPageEditor().getEditorSite().getShell(), Messages.getString("BupTraceGraph.buttonDialog"), //$NON-NLS-1$
+ sample.getKeyCode(), enumString, sample.getLabel(), sample.getComment(), false, sample.sampleSynchTime);
+ eventDialog.open();
+
+ if ( (eventDialog.getNewName() != null)
+ && (!eventDialog.getNewName().equals(sample.getLabel()))) {
+ sample.setLabel(eventDialog.getNewName());
+ redraw = true;
+ }
+
+ if ( (eventDialog.getNewComment() != null)
+ && (!eventDialog.getNewComment().equals(sample.getComment()))) {
+ sample.setComment(eventDialog.getNewComment());
+ redraw = true;
+ }
+
+ if (eventDialog.getNewSamePropagate()) {
+ Vector<BupSample> allSamples = (Vector<BupSample>)((GenericSampledTrace)this.getTrace()).samples;
+ for (BupSample currentSample : allSamples) {
+ if (currentSample.getKeyCode() == sample.getKeyCode()) {
+ currentSample.setLabel(eventDialog.getNewName());
+ }
+ }
+ redraw = true;
+ }
+ }
+
+ if (redraw)
+ ((FigureCanvas)me.getSource()).redraw();
+ }
+
+ public void mouseDragged(MouseEvent me) {}
+
+ public void mouseEntered(MouseEvent me) {}
+
+ public void mouseExited(MouseEvent me) {}
+
+ public void mouseDown(MouseEvent me) {}
+
+ public void mouseUp(MouseEvent me) {}
+
+ public static boolean openButtonDialog(int buttonIndex)
+ {
+ boolean redraw = false;
+
+ BupTrace bupTrace = (BupTrace)NpiInstanceRepository.getInstance().activeUidGetTrace("com.nokia.carbide.cpp.pi.button"); //$NON-NLS-1$
+
+ if (buttonIndex > bupTrace.samples.size() || buttonIndex < 1)
+ return false;
+
+ BupSample sample = bupTrace.getBupSample(buttonIndex - 1);
+
+ // let them change some information
+ Display display = PIPageEditor.currentPageEditor().getEditorSite().getShell().getDisplay();
+
+ GridData gridData;
+
+ IBupEventMap map = bupTrace.getCurrentBupMapInUse();
+ String enumString = map.getEnum(sample.getKeyCode());
+
+ BupEventDialog eventDialog = new BupEventDialog(PIPageEditor.currentPageEditor().getEditorSite().getShell(), Messages.getString("BupTraceGraph.buttonDialog"), //$NON-NLS-1$
+ sample.getKeyCode(), enumString, sample.getLabel(), sample.getComment(), false, sample.sampleSynchTime);
+ eventDialog.open();
+
+ if ( (eventDialog.getNewName() != null)
+ && (!eventDialog.getNewName().equals(sample.getLabel()))) {
+ sample.setLabel(eventDialog.getNewName());
+ redraw = true;
+ }
+
+ if ( (eventDialog.getNewComment() != null)
+ && (!eventDialog.getNewComment().equals(sample.getComment()))) {
+ sample.setComment(eventDialog.getNewComment());
+ redraw = true;
+ }
+
+ if (eventDialog.getNewSamePropagate()) {
+ Vector<BupSample> allSamples = (Vector<BupSample>)bupTrace.samples;
+ for (BupSample currentSample : allSamples) {
+ if (currentSample.getKeyCode() == sample.getKeyCode()) {
+ currentSample.setLabel(eventDialog.getNewName());
+ }
+ }
+ redraw = true;
+ }
+
+ return true;
+ }
+
+ public void addContextMenuItems(Menu menu, MouseEvent me)
+ {
+ if (!display_events)
+ return;
+
+ long x = me.x;
+ long y = me.y;
+
+ int height = this.getVisualSize().height;
+
+ // make sure we're in the right area of the graph window
+ if ((y < height - EVENT_BOTTOMOFLINE) || (y > height - EVENT_BOTTOMOFLINE + EVENT_RECTHEIGHT + 2))
+ return;
+
+ Enumeration samples = ((GenericSampledTrace) this.getTrace()).samples.elements();
+ double scale = this.getScale();
+
+ boolean found = false;
+
+ // unlike mouseMove, the x coordinate is not relative to the FigureCanvas
+ x += ((FigureCanvas)me.getSource()).getViewport().getViewLocation().x;
+
+ while (samples.hasMoreElements())
+ {
+ BupSample sample = (BupSample)samples.nextElement();
+ long xSample = (long)(sample.sampleSynchTime/scale + 0.5);
+
+ // samples are in timestamp order, so stop when xSample + EVENT_RECTWIDTH is too high
+ if (x < xSample - EVENT_RECTWIDTH)
+ break;
+
+ if ((x >= xSample - EVENT_RECTWIDTH) && (x <= xSample + EVENT_RECTWIDTH))
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
+ return;
+
+ new MenuItem(menu, SWT.SEPARATOR);
+
+ final MouseEvent meFinal = me;
+
+ MenuItem changeEventItem = new MenuItem(menu, SWT.PUSH);
+ changeEventItem.setText(Messages.getString("BupTraceGraph.changeEvent")); //$NON-NLS-1$
+ changeEventItem.addSelectionListener(new SelectionAdapter() {
+ public void widgetSelected(SelectionEvent e) {
+ mouseDoubleClick(meFinal);
+ }
+ });
+
+ int startTime = (int) this.getSelectionStart();
+ int endTime = (int) this.getSelectionEnd();
+
+ // save raw samples
+ Vector sampleVector = ((GenericSampledTrace) this.getTrace()).samples;
+
+ int i = 0;
+ while (i < sampleVector.size() && ((BupSample) sampleVector.get(i)).sampleSynchTime < startTime)
+ i++;
+
+ // enable if we have at least one event in the interval
+ getSaveSamplesItem(menu, (i < sampleVector.size() && ((BupSample) sampleVector.get(i)).sampleSynchTime <= endTime));
+ }
+
+ public void saveEventSamples() {
+ SaveSampleString saveSampleString = new SaveSampleString();
+ actionSaveSamples(saveSampleString); //$NON-NLS-1$
+ }
+
+ public void paintLeftLegend(FigureCanvas figureCanvas, GC gc) {
+ }
+}