From: Patrick Tasse Date: Thu, 21 Aug 2014 19:27:39 +0000 (-0400) Subject: tmf: Add cycles time format and delta format in time graph X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=0fab12b0f3f481a91b0d61e1a8dfbcb4d944758a;p=deliverable%2Ftracecompass.git tmf: Add cycles time format and delta format in time graph Change-Id: Iaa0e750971bf7b06a6209f7528e8c293be816d9c Signed-off-by: Patrick Tasse Reviewed-on: https://git.eclipse.org/r/33339 Tested-by: Hudson CI Reviewed-by: Alexandre Montplaisir --- diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java index 06e3683c70..17a6591dac 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/Messages.java @@ -119,6 +119,8 @@ public class Messages extends NLS { public static String TmfTimeGraphViewer_FollowArrowBackwardActionNameText; public static String TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText; + public static String Utils_ClockCyclesUnit; + public static String ColorsView_AddActionToolTipText; public static String ColorsView_BackgroundButtonText; public static String ColorsView_BackgroundDialogText; diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties index 4b3c6bc997..07789b254d 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/messages.properties @@ -115,6 +115,8 @@ TmfTimeGraphViewer_FollowArrowForwardActionToolTipText=Follow Arrow Forward TmfTimeGraphViewer_FollowArrowBackwardActionNameText=Follow Arrow Backward TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText=Follow Arrow Backward +Utils_ClockCyclesUnit=\u0020cc + # org.eclipse.linuxtools.tmf.ui.views.colors ColorsView_AddActionToolTipText=Insert new color setting ColorsView_BackgroundButtonText=BG diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java index 5b7ab9a284..db8c53d45a 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/TimeGraphViewer.java @@ -33,6 +33,7 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphScale; @@ -77,6 +78,7 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { private static final int DEFAULT_HEIGHT = 22; private static final long RECENTERING_MARGIN_FACTOR = 50; private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$ + private static final long DEFAULT_FREQUENCY = 1000000000L; private long fMinTimeInterval; private ITimeGraphEntry fSelectedEntry; @@ -103,14 +105,18 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { private Object fInputElement; private ITimeGraphContentProvider fTimeGraphContentProvider; private ITimeGraphPresentationProvider fTimeGraphProvider; + private ITimeDataProvider fTimeDataProvider = this; + private TimeGraphTooltipHandler fToolTipHandler; private List fSelectionListeners = new ArrayList<>(); private List fTimeListeners = new ArrayList<>(); private List fRangeListeners = new ArrayList<>(); - // Time format, using Epoch reference, Relative time format(default) or - // Number + // Time format, using Epoch reference, Relative time format(default), + // Number, or Cycles private TimeFormat fTimeFormat = TimeFormat.RELATIVE; + // Clock frequency to use for Cycles time format + private long fClockFrequency = DEFAULT_FREQUENCY; private int fBorderWidth = 0; private int fTimeScaleHeight = DEFAULT_HEIGHT; @@ -181,8 +187,8 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { fTimeGraphProvider = timeGraphProvider; fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider); - TimeGraphTooltipHandler toolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, this); - toolTipHandler.activateHoverHelp(fTimeGraphCtrl); + fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider); + fToolTipHandler.activateHoverHelp(fTimeGraphCtrl); } /** @@ -345,7 +351,7 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { fDataViewer.setLayout(gl); fTimeScaleCtrl = new TimeGraphScale(fDataViewer, fColorScheme); - fTimeScaleCtrl.setTimeProvider(this); + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); fTimeScaleCtrl.setHeight(fTimeScaleHeight); @@ -1057,6 +1063,33 @@ public class TimeGraphViewer implements ITimeDataProvider, SelectionListener { */ public void setTimeFormat(TimeFormat tf) { this.fTimeFormat = tf; + if (tf == TimeFormat.CYCLES) { + fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); + } else { + fTimeDataProvider = this; + } + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); + if (fToolTipHandler != null) { + fToolTipHandler.setTimeProvider(fTimeDataProvider); + } + } + + /** + * Sets the clock frequency. Used when the time format is set to CYCLES. + * + * @param clockFrequency + * the clock frequency in Hz + * @since 3.1 + */ + public void setClockFrequency(long clockFrequency) { + fClockFrequency = clockFrequency; + if (fTimeFormat == TimeFormat.CYCLES) { + fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency); + fTimeScaleCtrl.setTimeProvider(fTimeDataProvider); + if (fToolTipHandler != null) { + fToolTipHandler.setTimeProvider(fTimeDataProvider); + } + } } /** diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java new file mode 100644 index 0000000000..c859aecc10 --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/ITimeDataProviderConverter.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * 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: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; + +/** + * Time data provider that converts between time data units used internally and + * time in display units used by the caller. + * + * @since 3.1 + */ +public interface ITimeDataProviderConverter extends ITimeDataProvider { + + /** + * Convert a time in time data provider units to a time in display units. + * + * @param time the time in time data provider units + * + * @return the time in display units + */ + long convertTime(long time); +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java new file mode 100644 index 0000000000..aa4cd06a2f --- /dev/null +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeDataProviderCyclesConverter.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2014 Ericsson + * + * 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: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; + +/** + * Time Data Provider wrapper that converts nanoseconds to cycles. + * + * The user of the wrapper uses cycles, the wrapped provider uses nanoseconds. + * @since 3.1 + * + */ +public class TimeDataProviderCyclesConverter implements ITimeDataProviderConverter { + + private static final long GIGAHERTZ = 1000000000L; + + private final @NonNull ITimeDataProvider fProvider; + private final long fFreq; + + /** + * Constructor + * + * @param provider + * the original time data provider + * @param clockFrequency + * the clock frequency in Hz + */ + public TimeDataProviderCyclesConverter(@NonNull ITimeDataProvider provider, long clockFrequency) { + fProvider = provider; + fFreq = clockFrequency; + } + + /** + * Convert nanoseconds to cycles + * + * @param nanos + * time in nanoseconds + * @return time in cycles + */ + public long toCycles(long nanos) { + return Math.round(nanos * ((double) fFreq / GIGAHERTZ)); + } + + /** + * Convert cycles to nanoseconds + * + * @param cycles + * time in cycles + * @return time in nanoseconds + */ + public long toNanos(long cycles) { + return Math.round(cycles * ((double) GIGAHERTZ / fFreq)); + } + + @Override + public long convertTime(long time) { + return toCycles(time); + } + + @Override + public void setSelectionRangeNotify(long beginTime, long endTime) { + fProvider.setSelectionRangeNotify(toNanos(beginTime), toNanos(endTime)); + } + + @Override + public void setSelectionRange(long beginTime, long endTime) { + fProvider.setSelectionRange(toNanos(beginTime), toNanos(endTime)); + } + + @Override + public long getSelectionBegin() { + return toCycles(fProvider.getSelectionBegin()); + } + + @Override + public long getSelectionEnd() { + return toCycles(fProvider.getSelectionEnd()); + } + + @Override + public long getBeginTime() { + return toCycles(fProvider.getBeginTime()); + } + + @Override + public long getEndTime() { + return toCycles(fProvider.getEndTime()); + } + + @Override + public long getMinTime() { + return toCycles(fProvider.getMinTime()); + } + + @Override + public long getMaxTime() { + return toCycles(fProvider.getMaxTime()); + } + + @Override + public long getTime0() { + return toCycles(fProvider.getTime0()); + } + + @Override + public long getTime1() { + return toCycles(fProvider.getTime1()); + } + + @Override + public long getMinTimeInterval() { + // do not convert: this is in integer units + return fProvider.getMinTimeInterval(); + } + + @Override + public void setStartFinishTimeNotify(long time0, long time1) { + fProvider.setStartFinishTimeNotify(toNanos(time0), toNanos(time1)); + } + + @Override + public void setStartFinishTime(long time0, long time1) { + fProvider.setStartFinishTime(toNanos(time0), toNanos(time1)); + } + + @Override + public void notifyStartFinishTime() { + fProvider.notifyStartFinishTime(); + } + + @Override + public void setSelectedTimeNotify(long time, boolean ensureVisible) { + fProvider.setSelectedTimeNotify(toNanos(time), ensureVisible); + } + + @Override + public void setSelectedTime(long time, boolean ensureVisible) { + fProvider.setSelectedTime(toNanos(time), ensureVisible); + } + + @Override + public void resetStartFinishTime() { + fProvider.resetStartFinishTime(); + } + + @Override + public int getNameSpace() { + return fProvider.getNameSpace(); + } + + @Override + public void setNameSpace(int width) { + fProvider.setNameSpace(width); + } + + @Override + public int getTimeSpace() { + return fProvider.getTimeSpace(); + } + + @Override + public TimeFormat getTimeFormat() { + return fProvider.getTimeFormat(); + } + +} diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java index d053ccc618..8b433a8ec6 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphControl.java @@ -35,9 +35,6 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.ViewerFilter; -import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfNanoTimestamp; -import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestampDelta; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphColorListener; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.ITimeGraphPresentationProvider2; @@ -49,6 +46,9 @@ import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.TimeGraphTreeExpansionEve import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ILinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.ControlListener; @@ -2054,38 +2054,54 @@ public class TimeGraphControl extends TimeGraphBaseControl } private void updateStatusLine(int x) { - if (fStatusLineManager == null || null == fTimeProvider || - fTimeProvider.getTime0() == fTimeProvider.getTime1()) { + // use the time provider of the time graph scale for the status line + ITimeDataProvider tdp = fTimeGraphScale.getTimeProvider(); + if (fStatusLineManager == null || null == tdp || + tdp.getTime0() == tdp.getTime1()) { return; } + TimeFormat tf = tdp.getTimeFormat(); + Resolution res = Resolution.NANOSEC; StringBuilder message = new StringBuilder(); if (x >= 0 && fDragState == DRAG_NONE) { long time = getTimeAtX(x); if (time >= 0) { - message.append("T: "); //$NON-NLS-1$ - message.append(new TmfNanoTimestamp(time).toString()); - message.append(" T1: "); //$NON-NLS-1$ - long selectionBegin = fTimeProvider.getSelectionBegin(); - long selectionEnd = fTimeProvider.getSelectionEnd(); - message.append(new TmfNanoTimestamp(Math.min(selectionBegin, selectionEnd)).toString()); + if (tdp instanceof ITimeDataProviderConverter) { + time = ((ITimeDataProviderConverter) tdp).convertTime(time); + } + long selectionBegin = tdp.getSelectionBegin(); + long selectionEnd = tdp.getSelectionEnd(); + message.append(NLS.bind("T: {0}{1} T1: {2}{3}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(time) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(time, tf, res), + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.min(selectionBegin, selectionEnd), tf, res) + })); if (selectionBegin != selectionEnd) { - message.append(" T2: "); //$NON-NLS-1$ - message.append(new TmfNanoTimestamp(Math.max(selectionBegin, selectionEnd)).toString()); - message.append(" \u0394: "); //$NON-NLS-1$ - message.append(new TmfTimestampDelta(Math.abs(selectionBegin - selectionEnd), ITmfTimestamp.NANOSECOND_SCALE)); + message.append(NLS.bind(" T2: {0}{1} \u0394: {2}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(selectionBegin, selectionEnd)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.max(selectionBegin, selectionEnd), tf, res), + Utils.formatDelta(Math.abs(selectionBegin - selectionEnd), tf, res) + })); } } } else if (fDragState == DRAG_SELECTION || fDragState == DRAG_ZOOM) { long time0 = fDragTime0; long time = getTimeAtX(fDragX); - message.append("T1: "); //$NON-NLS-1$ - message.append(new TmfNanoTimestamp(Math.min(time, time0)).toString()); - if (time != time0) { - message.append(" T2: "); //$NON-NLS-1$ - message.append(new TmfNanoTimestamp(Math.max(time, time0)).toString()); - message.append(" \u0394: "); //$NON-NLS-1$ - message.append(new TmfTimestampDelta(Math.abs(time - time0), ITmfTimestamp.NANOSECOND_SCALE)); - } + if (tdp instanceof ITimeDataProviderConverter) { + time0 = ((ITimeDataProviderConverter) tdp).convertTime(time0); + time = ((ITimeDataProviderConverter) tdp).convertTime(time); + } + message.append(NLS.bind("T1: {0}{1} T2: {2}{3} \u0394: {4}", //$NON-NLS-1$ + new Object[] { + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.min(time, time0)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.min(time, time0), tf, res), + tf == TimeFormat.CALENDAR ? Utils.formatDate(Math.max(time, time0)) + ' ' : "", //$NON-NLS-1$ + Utils.formatTime(Math.max(time, time0), tf, res), + Utils.formatDelta(Math.abs(time - time0), tf, res) + })); } fStatusLineManager.setMessage(message.toString()); } @@ -2251,6 +2267,7 @@ public class TimeGraphControl extends TimeGraphBaseControl setCapture(true); fDragX = Math.min(Math.max(e.x, fTimeProvider.getNameSpace()), getCtrlSize().x - RIGHT_MARGIN); fDragX0 = fDragX; + fDragTime0 = getTimeAtX(fDragX0); fDragState = DRAG_ZOOM; fDragButton = e.button; redraw(); diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java index 1dda20588f..a67b748e98 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphScale.java @@ -21,6 +21,7 @@ import java.util.Calendar; import java.util.Date; import java.util.TimeZone; +import org.eclipse.linuxtools.internal.tmf.ui.Messages; import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; import org.eclipse.linuxtools.tmf.core.signal.TmfTimestampFormatUpdateSignal; @@ -79,6 +80,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements private static final TimeDraw TIMEDRAW_ABS_MONTH = new TimeDrawAbsMonth(); private static final TimeDraw TIMEDRAW_ABS_YEAR = new TimeDrawAbsYear(); private static final TimeDraw TIMEDRAW_NUMBER = new TimeDrawNumber(); + private static final TimeDraw TIMEDRAW_CYCLES = new TimeDrawCycles(); private static final int DRAG_EXTERNAL = -1; private static final int NO_BUTTON = 0; @@ -125,6 +127,16 @@ public class TimeGraphScale extends TimeGraphBaseControl implements fTimeProvider = timeProvider; } + /** + * Get the time provider used by this scale + * + * @return The time provider + * @since 3.1 + */ + public ITimeDataProvider getTimeProvider() { + return fTimeProvider; + } + @Override public Point computeSize(int wHint, int hHint, boolean changed) { return super.computeSize(wHint, fHeight, changed); @@ -166,7 +178,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements long timeDelta; double minDelta = (pixelsPerNanoSec == 0) ? YEAR_IN_NS : width / pixelsPerNanoSec; long unit = 1; - if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) { + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { if (minDelta > 6 * MONTH_IN_NS) { unit = YEAR_IN_NS; } else if (minDelta > 3 * MONTH_IN_NS) { @@ -213,8 +225,8 @@ public class TimeGraphScale extends TimeGraphBaseControl implements TimeDraw getTimeDraw(long timeDelta) { TimeDraw timeDraw; if (fTimeProvider != null) { - - if (fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { + switch (fTimeProvider.getTimeFormat()) { + case CALENDAR: if (timeDelta >= YEAR_IN_NS) { timeDraw = TIMEDRAW_ABS_YEAR; } else if (timeDelta >= MONTH_IN_NS) { @@ -235,9 +247,12 @@ public class TimeGraphScale extends TimeGraphBaseControl implements timeDraw = TIMEDRAW_ABS_NANOSEC; } return timeDraw; - } else if (fTimeProvider.getTimeFormat() == TimeFormat.NUMBER) { - timeDraw = TIMEDRAW_NUMBER; - return timeDraw; + case NUMBER: + return TIMEDRAW_NUMBER; + case CYCLES: + return TIMEDRAW_CYCLES; + case RELATIVE: + default: } } @@ -329,7 +344,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements rect0.width = labelWidth; long time; - if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) { + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { time = floorToCalendar(time0, timeDelta); } else { time = (time0 / timeDelta) * timeDelta; @@ -340,7 +355,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements int y = rect0.y + rect0.height; - if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) { + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { timeDraw.drawAbsHeader(gc, time, absHeaderRect); } @@ -359,7 +374,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements if (pixelsPerNanoSec == 0 || time > Long.MAX_VALUE - timeDelta || timeDelta == 0) { break; } - if (fTimeProvider != null && fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) { + if (fTimeProvider != null && fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { if (timeDelta >= YEAR_IN_NS) { long millis = time / MILLISEC_IN_NS; GREGORIAN_CALENDAR.setTime(new Date(millis)); @@ -452,7 +467,7 @@ public class TimeGraphScale extends TimeGraphBaseControl implements int numDigits = 5; long timeRange = time1 - time0; - if (fTimeProvider.getTimeFormat().equals(TimeFormat.CALENDAR)) { + if (fTimeProvider.getTimeFormat() == TimeFormat.CALENDAR) { // Calculate the number of digits to represent the minutes provided // 11:222 // HH:mm:ss @@ -470,6 +485,9 @@ public class TimeGraphScale extends TimeGraphBaseControl implements int thousandGroups = (numDigits - 1) / 3; numDigits += thousandGroups; numDigits += 12; // .000 000 000 + if (fTimeProvider.getTimeFormat() == TimeFormat.CYCLES) { + numDigits += Messages.Utils_ClockCyclesUnit.length(); + } } return numDigits; @@ -619,7 +637,7 @@ abstract class TimeDraw { return s + n; } - public abstract void draw(GC gc, long time, Rectangle rect); + public abstract int draw(GC gc, long time, Rectangle rect); /** * Override to draw absolute time header. This is for the time information @@ -638,68 +656,68 @@ abstract class TimeDraw { class TimeDrawSec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { long sec = nanosec / SEC_IN_NS; - Utils.drawText(gc, sep(sec), rect, true); + return Utils.drawText(gc, sep(sec), rect, true); } } class TimeDrawMillisec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { long millisec = nanosec / MILLISEC_IN_NS; long ms = millisec % PAD_1000; long sec = millisec / SEC_IN_MS; - Utils.drawText(gc, sep(sec) + "." + pad(ms), rect, true); //$NON-NLS-1$ + return Utils.drawText(gc, sep(sec) + "." + pad(ms), rect, true); //$NON-NLS-1$ } } class TimeDrawMicrosec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { long microsec = nanosec / MICROSEC_IN_NS; long us = microsec % PAD_1000; long millisec = microsec / MILLISEC_IN_US; long ms = millisec % PAD_1000; long sec = millisec / SEC_IN_MS; - Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ + return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ } } class TimeDrawNanosec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { long ns = nanosec % PAD_1000; long microsec = nanosec / MICROSEC_IN_NS; long us = microsec % PAD_1000; long millisec = microsec / MILLISEC_IN_US; long ms = millisec % PAD_1000; long sec = millisec / SEC_IN_MS; - Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + return Utils.drawText(gc, sep(sec) + "." + pad(ms) + " " + pad(us) + " " + pad(ns), rect, true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } class TimeDrawAbsYear extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = YEAR_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } } class TimeDrawAbsMonth extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = MONTH_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } } class TimeDrawAbsDay extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = DAY_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } @Override @@ -715,9 +733,9 @@ class TimeDrawAbsDay extends TimeDraw { class TimeDrawAbsHrs extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = HOURS_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } @Override @@ -733,9 +751,9 @@ class TimeDrawAbsHrs extends TimeDraw { class TimeDrawAbsMin extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = MIN_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } @Override @@ -751,9 +769,9 @@ class TimeDrawAbsMin extends TimeDraw { class TimeDrawAbsSec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); } @Override @@ -769,11 +787,10 @@ class TimeDrawAbsSec extends TimeDraw { class TimeDrawAbsMillisec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); String ns = Utils.formatNs(nanosec, Resolution.MILLISEC); - - Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ + return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ } @Override @@ -789,10 +806,10 @@ class TimeDrawAbsMillisec extends TimeDraw { class TimeDrawAbsMicroSec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); String micr = Utils.formatNs(nanosec, Resolution.MICROSEC); - Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$ + return Utils.drawText(gc, stime + "." + micr, rect, true); //$NON-NLS-1$ } @Override @@ -808,10 +825,10 @@ class TimeDrawAbsMicroSec extends TimeDraw { class TimeDrawAbsNanoSec extends TimeDraw { @Override - public void draw(GC gc, long nanosec, Rectangle rect) { + public int draw(GC gc, long nanosec, Rectangle rect) { String stime = SEC_FORMAT.format(new Date(nanosec / MILLISEC_IN_NS)); String ns = Utils.formatNs(nanosec, Resolution.NANOSEC); - Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ + return Utils.drawText(gc, stime + "." + ns, rect, true); //$NON-NLS-1$ } @Override @@ -827,8 +844,16 @@ class TimeDrawAbsNanoSec extends TimeDraw { class TimeDrawNumber extends TimeDraw { @Override - public void draw(GC gc, long time, Rectangle rect) { + public int draw(GC gc, long time, Rectangle rect) { String stime = NumberFormat.getInstance().format(time); - Utils.drawText(gc, stime, rect, true); + return Utils.drawText(gc, stime, rect, true); + } +} + +class TimeDrawCycles extends TimeDraw { + @Override + public int draw(GC gc, long time, Rectangle rect) { + String stime = Utils.formatTime(time, TimeFormat.CYCLES, Resolution.SECONDS); + return Utils.drawText(gc, stime, rect, true); } } diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java index 9bc79c36d2..672108f22e 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/TimeGraphTooltipHandler.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2007, 2013 Intel Corporation, Ericsson + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson * 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 @@ -53,7 +53,7 @@ public class TimeGraphTooltipHandler { private Shell fTipShell; private Composite fTipComposite; - private final ITimeDataProvider fTimeDataProvider; + private ITimeDataProvider fTimeDataProvider; private ITimeGraphPresentationProvider fTimeGraphProvider = null; /** @@ -73,6 +73,18 @@ public class TimeGraphTooltipHandler { this.fTimeDataProvider = timeProv; } + /** + * Set the time data provider + * + * @param timeDataProvider + * The time data provider + * + * @since 3.1 + */ + public void setTimeProvider(ITimeDataProvider timeDataProvider) { + fTimeDataProvider = timeDataProvider; + } + private void createTooltipShell(Shell parent) { final Display display = parent.getDisplay(); if (fTipShell != null && ! fTipShell.isDisposed()) { @@ -209,33 +221,46 @@ public class TimeGraphTooltipHandler { Resolution res = Resolution.NANOSEC; TimeFormat tf = fTimeDataProvider.getTimeFormat(); + String startTime = "?"; //$NON-NLS-1$ + String duration = "?"; //$NON-NLS-1$ + String endTime = "?"; //$NON-NLS-1$ + if (fTimeDataProvider instanceof ITimeDataProviderConverter) { + ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; + if (eventStartTime > -1) { + eventStartTime = tdp.convertTime(eventStartTime); + startTime = Utils.formatTime(eventStartTime, tf, res); + } + if (eventEndTime > -1) { + eventEndTime = tdp.convertTime(eventEndTime); + endTime = Utils.formatTime(eventEndTime, tf, res); + } + if (eventDuration > -1) { + duration = Utils.formatDelta(eventEndTime - eventStartTime, tf, res); + } + } else { + if (eventStartTime > -1) { + startTime = Utils.formatTime(eventStartTime, tf, res); + } + if (eventEndTime > -1) { + endTime = Utils.formatTime(eventEndTime, tf, res); + } + if (eventDuration > -1) { + duration = Utils.formatDelta(eventDuration, tf, res); + } + } if (tf == TimeFormat.CALENDAR) { - addItem(Messages.TmfTimeTipHandler_TRACE_DATE, eventStartTime > -1 ? - Utils.formatDate(eventStartTime) - : "?"); //$NON-NLS-1$ + addItem(Messages.TmfTimeTipHandler_TRACE_DATE, + eventStartTime > -1 ? Utils.formatDate(eventStartTime) : "?"); //$NON-NLS-1$ } if (eventDuration > 0) { - addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, eventStartTime > -1 ? - Utils.formatTime(eventStartTime, tf, res) - : "?"); //$NON-NLS-1$ - - addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, eventEndTime > -1 ? - Utils.formatTime(eventEndTime, tf, res) - : "?"); //$NON-NLS-1$ + addItem(Messages.TmfTimeTipHandler_TRACE_START_TIME, startTime); + addItem(Messages.TmfTimeTipHandler_TRACE_STOP_TIME, endTime); } else { - addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, eventStartTime > -1 ? - Utils.formatTime(eventStartTime, tf, res) - : "?"); //$NON-NLS-1$ + addItem(Messages.TmfTimeTipHandler_TRACE_EVENT_TIME, startTime); } if (eventDuration > 0) { - // Duration in relative format in any case - if (tf == TimeFormat.CALENDAR) { - tf = TimeFormat.RELATIVE; - } - addItem(Messages.TmfTimeTipHandler_DURATION, eventDuration > -1 ? - Utils.formatTime(eventDuration, tf, res) - : "?"); //$NON-NLS-1$ + addItem(Messages.TmfTimeTipHandler_DURATION, duration); } } } @@ -257,7 +282,12 @@ public class TimeGraphTooltipHandler { long sourceTime = linkEvent.getTime(); long duration = linkEvent.getDuration(); long targetTime = sourceTime + duration; - + if (fTimeDataProvider instanceof ITimeDataProviderConverter) { + ITimeDataProviderConverter tdp = (ITimeDataProviderConverter) fTimeDataProvider; + sourceTime = tdp.convertTime(sourceTime); + targetTime = tdp.convertTime(targetTime); + duration = targetTime - sourceTime; + } Resolution res = Resolution.NANOSEC; TimeFormat tf = fTimeDataProvider.getTimeFormat(); if (tf == TimeFormat.CALENDAR) { @@ -266,11 +296,7 @@ public class TimeGraphTooltipHandler { if (duration > 0) { addItem(Messages.TmfTimeTipHandler_LINK_SOURCE_TIME, Utils.formatTime(sourceTime, tf, res)); addItem(Messages.TmfTimeTipHandler_LINK_TARGET_TIME, Utils.formatTime(targetTime, tf, res)); - // Duration in relative format in any case - if (tf == TimeFormat.CALENDAR) { - tf = TimeFormat.RELATIVE; - } - addItem(Messages.TmfTimeTipHandler_DURATION, Utils.formatTime(duration, tf, res)); + addItem(Messages.TmfTimeTipHandler_DURATION, Utils.formatDelta(duration, tf, res)); } else { addItem(Messages.TmfTimeTipHandler_LINK_TIME, Utils.formatTime(sourceTime, tf, res)); } diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java index 364c90cccb..f10a9061a8 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/widgets/timegraph/widgets/Utils.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2007, 2013 Intel Corporation, Ericsson + * Copyright (c) 2007, 2014 Intel Corporation, Ericsson * 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 @@ -20,7 +20,9 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +import org.eclipse.linuxtools.internal.tmf.ui.Messages; import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimePreferences; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; @@ -59,6 +61,12 @@ public class Utils { * @since 2.0 */ NUMBER, + + /** + * Timestamp displayed as cycles + * @since 3.1 + */ + CYCLES } /** @@ -80,6 +88,9 @@ public class Utils { private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat("HH:mm:ss"); //$NON-NLS-1$ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); //$NON-NLS-1$ + private static final long HOURS_PER_DAY = 24; + private static final long MIN_PER_HOUR = 60; + private static final long SEC_PER_MIN = 60; private static final long SEC_IN_NS = 1000000000; private static final long MILLISEC_IN_NS = 1000000; @@ -251,8 +262,8 @@ public class Utils { * @param rect * The rectangle object which is being drawn * @param transp - * Should we transpose the color - * @return The X coordinate where we have written + * If true the background will be transparent + * @return The width of the written text */ public static int drawText(GC gc, String text, Rectangle rect, boolean transp) { Point size = gc.stringExtent(text); @@ -272,8 +283,8 @@ public class Utils { * @param y * the Y coordinate of the starting point * @param transp - * Should we transpose the color - * @return The X coordinate where we have written + * If true the background will be transparent + * @return The width of the written text */ public static int drawText(GC gc, String text, int x, int y, boolean transp) { Point size = gc.stringExtent(text); @@ -334,11 +345,15 @@ public class Utils { * @return the formatted time */ public static String formatTime(long time, TimeFormat format, Resolution resolution) { - // if format is absolute (Calendar) - if (format == TimeFormat.CALENDAR) { + switch (format) { + case CALENDAR: return formatTimeAbs(time, resolution); - } else if (format == TimeFormat.NUMBER) { + case NUMBER: return NumberFormat.getInstance().format(time); + case CYCLES: + return NumberFormat.getInstance().format(time) + Messages.Utils_ClockCyclesUnit; + case RELATIVE: + default: } StringBuffer str = new StringBuffer(); @@ -394,6 +409,66 @@ public class Utils { return str.toString(); } + /** + * Formats time delta + * + * @param delta + * The time delta, in ns + * @param format + * The time format to use + * @param resolution + * The resolution to use + * @since 3.1 + * @return the formatted time delta + */ + public static String formatDelta(long delta, TimeFormat format, Resolution resolution) { + if (format == TimeFormat.CALENDAR) { + return formatDeltaAbs(delta, resolution); + } + return formatTime(delta, format, resolution); + } + + /** + * Formats time delta in ns to Calendar format, only formatting the years, + * days, hours or minutes if necessary. + * + * @param delta + * The time delta, in ns + * @param resolution + * The resolution to use + * @return the formatted time delta + * @since 3.1 + */ + public static String formatDeltaAbs(long delta, Resolution resolution) { + StringBuffer str = new StringBuffer(); + if (delta < 0) { + str.append('-'); + } + long ns = Math.abs(delta); + long seconds = TimeUnit.NANOSECONDS.toSeconds(ns); + long minutes = TimeUnit.NANOSECONDS.toMinutes(ns); + long hours = TimeUnit.NANOSECONDS.toHours(ns); + long days = TimeUnit.NANOSECONDS.toDays(ns); + if (days > 0) { + str.append(days); + str.append("d "); //$NON-NLS-1$ + } + if (hours > 0) { + str.append(hours % HOURS_PER_DAY); + str.append("h "); //$NON-NLS-1$ + } + if (minutes > 0) { + str.append(minutes % MIN_PER_HOUR); + str.append("m "); //$NON-NLS-1$ + } + str.append(seconds % SEC_PER_MIN); + str.append('.'); + // append the ms, us and ns as specified in the resolution + str.append(formatNs(delta, resolution)); + str.append("s"); //$NON-NLS-1$ + return str.toString(); + } + /** * Obtains the remainder fraction on unit Seconds of the entered value in * nanoseconds. e.g. input: 1241207054171080214 ns The number of fraction