sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.button/src/com/nokia/carbide/cpp/pi/button/BupTraceGraph.java
changeset 2 b9ab3b238396
child 5 844b047e260d
--- /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) {
+	}
+}