From 79ec0b893fbf988ad50b2aa7163d8a1c4ff10fa5 Mon Sep 17 00:00:00 2001 From: Patrick Tasse Date: Mon, 5 Aug 2013 15:02:08 -0400 Subject: [PATCH] lttng: Add arrows in Control Flow view Show arrows to follow CPU execution in Control Flow view. Implement a Hide Arrows toggle action to the time graph control. Change-Id: Ic6e5020f8a7895e482bda9e45c8333dde79e7022 Signed-off-by: Patrick Tasse Reviewed-on: https://git.eclipse.org/r/15147 Tested-by: Hudson CI Reviewed-by: Genevieve Bastien --- .../ui/views/controlflow/ControlFlowView.java | 85 ++++++++++++++++++ .../icons/elcl16/hide_arrows.gif | Bin 0 -> 111 bytes .../internal/tmf/ui/ITmfImageConstants.java | 2 + .../linuxtools/internal/tmf/ui/Messages.java | 2 + .../internal/tmf/ui/messages.properties | 2 + .../timegraph/AbstractTimeGraphView.java | 15 +++- .../ui/widgets/timegraph/TimeGraphViewer.java | 84 +++++++++++++---- .../timegraph/widgets/TimeGraphControl.java | 15 ++++ 8 files changed, 185 insertions(+), 20 deletions(-) create mode 100644 org.eclipse.linuxtools.tmf.ui/icons/elcl16/hide_arrows.gif diff --git a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index da4666f4b8..f9ba9dd809 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.linuxtools.lttng2.kernel.ui/src/org/eclipse/linuxtools/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -19,7 +19,10 @@ import java.util.Comparator; import java.util.List; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.action.IToolBarManager; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; +import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Activator; import org.eclipse.linuxtools.internal.lttng2.kernel.ui.Messages; import org.eclipse.linuxtools.lttng2.kernel.core.trace.LttngKernelTrace; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; @@ -30,11 +33,14 @@ import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem; import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; import org.eclipse.linuxtools.tmf.ui.views.timegraph.AbstractTimeGraphView; +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.model.TimeEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.model.TimeLinkEvent; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.Resolution; import org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat; @@ -86,6 +92,17 @@ public class ControlFlowView extends AbstractTimeGraphView { setEntryComparator(new ControlFlowEntryComparator()); } + @Override + protected void fillLocalToolBar(IToolBarManager manager) { + IDialogSettings settings = Activator.getDefault().getDialogSettings(); + IDialogSettings section = settings.getSection(getClass().getName()); + if (section == null) { + section = settings.addNewSection(getClass().getName()); + } + manager.add(getTimeGraphCombo().getTimeGraphViewer().getHideArrowsAction(section)); + super.fillLocalToolBar(manager); + } + @Override protected String getNextText() { return Messages.ControlFlowView_nextProcessActionNameText; @@ -424,4 +441,72 @@ public class ControlFlowView extends AbstractTimeGraphView { } } } + + @Override + protected List getLinkList(long startTime, long endTime, long resolution, IProgressMonitor monitor) { + List list = new ArrayList(); + ITmfTrace[] traces = TmfTraceManager.getTraceSet(getTrace()); + List entryList = getEntryListMap().get(getTrace()); + if (traces == null || entryList == null) { + return list; + } + for (ITmfTrace trace : traces) { + if (trace instanceof LttngKernelTrace) { + ITmfStateSystem ssq = trace.getStateSystems().get(LttngKernelTrace.STATE_ID); + try { + long start = Math.max(startTime, ssq.getStartTime()); + long end = Math.min(endTime, ssq.getCurrentEndTime()); + if (end < start) { + continue; + } + List currentThreadQuarks = ssq.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$ + for (int currentThreadQuark : currentThreadQuarks) { + List currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, start, end, resolution, monitor); + int prevThread = 0; + long prevEnd = 0; + for (ITmfStateInterval currentThreadInterval : currentThreadIntervals) { + if (monitor.isCanceled()) { + return null; + } + long time = currentThreadInterval.getStartTime(); + int thread = currentThreadInterval.getStateValue().unboxInt(); + if (thread > 0 && prevThread > 0 && thread != prevThread && time == prevEnd) { + ITimeGraphEntry prevEntry = findEntry(entryList, trace, prevThread); + ITimeGraphEntry nextEntry = findEntry(entryList, trace, thread); + list.add(new TimeLinkEvent(prevEntry, nextEntry, time, 0, 0)); + } + prevThread = thread; + prevEnd = currentThreadInterval.getEndTime() + 1; + } + } + } catch (TimeRangeException e) { + e.printStackTrace(); + } catch (AttributeNotFoundException e) { + e.printStackTrace(); + } catch (StateValueTypeException e) { + e.printStackTrace(); + } catch (StateSystemDisposedException e) { + /* Ignored */ + } + } + } + return list; + } + + private ControlFlowEntry findEntry(List entryList, ITmfTrace trace, int threadId) { + for (TimeGraphEntry entry : entryList) { + if (entry instanceof ControlFlowEntry) { + ControlFlowEntry controlFlowEntry = (ControlFlowEntry) entry; + if (controlFlowEntry.getThreadId() == threadId && controlFlowEntry.getTrace() == trace) { + return controlFlowEntry; + } else if (entry.hasChildren()) { + controlFlowEntry = findEntry(entry.getChildren(), trace, threadId); + if (controlFlowEntry != null) { + return controlFlowEntry; + } + } + } + } + return null; + } } diff --git a/org.eclipse.linuxtools.tmf.ui/icons/elcl16/hide_arrows.gif b/org.eclipse.linuxtools.tmf.ui/icons/elcl16/hide_arrows.gif new file mode 100644 index 0000000000000000000000000000000000000000..6fe858df88b35b40330bbf7febdf2172b4cf2709 GIT binary patch literal 111 zcmZ?wbhEHb events = getLinkList(fZoomStartTime, fZoomEndTime, fResolution, fMonitor); - fTimeGraphCombo.setLinks(events); - redraw(); + if (events != null) { + fTimeGraphCombo.setLinks(events); + redraw(); + } } private void zoom(TimeGraphEntry entry, IProgressMonitor monitor) { @@ -888,7 +890,12 @@ public abstract class AbstractTimeGraphView extends TmfView { fillLocalToolBar(bars.getToolBarManager()); } - private void fillLocalToolBar(IToolBarManager manager) { + /** + * Add actions to local tool bar manager + * + * @param manager the tool bar manager + */ + protected void fillLocalToolBar(IToolBarManager manager) { if (fFilterColumns.length > 0) { manager.add(fTimeGraphCombo.getShowFilterAction()); } 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 cbbb5b2190..02bbf5acaa 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 @@ -20,6 +20,8 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; +import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.ISelectionProvider; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.linuxtools.internal.tmf.ui.Activator; @@ -69,6 +71,7 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { private static final int MAX_NAME_WIDTH = 1000; 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 long fMinTimeInterval; private ITimeGraphEntry fSelectedEntry; @@ -98,7 +101,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { 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) or + // Number private TimeFormat fTimeFormat = TimeFormat.RELATIVE; private int fBorderWidth = 0; private int fTimeScaleHeight = DEFAULT_HEIGHT; @@ -111,6 +115,7 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { private Action fPreviousItemAction; private Action fZoomInAction; private Action fZoomOutAction; + private Action fHideArrowsAction; /** * Standard constructor @@ -127,7 +132,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { /** * Sets the timegraph provider used by this timegraph viewer. * - * @param timeGraphProvider the timegraph provider + * @param timeGraphProvider + * the timegraph provider */ public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) { fTimeGraphProvider = timeGraphProvider; @@ -137,10 +143,12 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * Sets or clears the input for this time graph viewer. - * The input array should only contain top-level elements. + * Sets or clears the input for this time graph viewer. The input array + * should only contain top-level elements. * - * @param input The input of this time graph viewer, or null if none + * @param input + * The input of this time graph viewer, or null if + * none */ public void setInput(ITimeGraphEntry[] input) { ITimeGraphEntry[] realInput = input; @@ -982,7 +990,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param tf the {@link TimeFormat} used to display timestamps + * @param tf + * the {@link TimeFormat} used to display timestamps * @since 2.0 */ public void setTimeFormat(TimeFormat tf) { @@ -1007,7 +1016,7 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { public void setBorderWidth(int borderWidth) { if (borderWidth > -1) { this.fBorderWidth = borderWidth; - GridLayout gl = (GridLayout)fDataViewer.getLayout(); + GridLayout gl = (GridLayout) fDataViewer.getLayout(); gl.marginHeight = borderWidth; } } @@ -1073,7 +1082,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { /** * Set the width for the name column * - * @param width The width + * @param width + * The width */ public void setNameWidthPref(int width) { fNameWidthPref = width; @@ -1126,7 +1136,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { /** * Return the x coordinate corresponding to a time * - * @param time the time + * @param time + * the time * @return the x coordinate corresponding to the time * * @since 2.0 @@ -1138,7 +1149,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { /** * Return the time corresponding to an x coordinate * - * @param x the x coordinate + * @param x + * the x coordinate * @return the time corresponding to the x coordinate * * @since 2.0 @@ -1445,6 +1457,40 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { return fZoomOutAction; } + /** + * Get the hide arrows action + * + * @param dialogSettings + * The dialog settings section where the state should be stored, + * or null + * + * @return The Action object + * + * @since 2.1 + */ + public Action getHideArrowsAction(final IDialogSettings dialogSettings) { + if (fHideArrowsAction == null) { + fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) { + @Override + public void run() { + boolean hideArrows = fHideArrowsAction.isChecked(); + fTimeGraphCtrl.hideArrows(hideArrows); + refresh(); + if (dialogSettings != null) { + dialogSettings.put(HIDE_ARROWS_KEY, hideArrows); + } + } + }; + fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText); + fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS)); + if (dialogSettings != null) { + boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY); + fTimeGraphCtrl.hideArrows(hideArrows); + fHideArrowsAction.setChecked(hideArrows); + } + } + return fHideArrowsAction; + } private void adjustVerticalScrollBar() { int topIndex = fTimeGraphCtrl.getTopIndex(); @@ -1464,7 +1510,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param listener a {@link MenuDetectListener} + * @param listener + * a {@link MenuDetectListener} * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) * @since 1.2 */ @@ -1473,7 +1520,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param listener a {@link MenuDetectListener} + * @param listener + * a {@link MenuDetectListener} * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener) * @since 1.2 */ @@ -1482,7 +1530,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param listener a {@link MenuDetectListener} + * @param listener + * a {@link MenuDetectListener} * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) * @since 1.2 */ @@ -1491,7 +1540,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param listener a {@link MenuDetectListener} + * @param listener + * a {@link MenuDetectListener} * @see org.eclipse.linuxtools.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener) * @since 1.2 */ @@ -1500,7 +1550,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param filter The filter object to be attached to the view + * @param filter + * The filter object to be attached to the view * @since 2.0 */ public void addFilter(ViewerFilter filter) { @@ -1509,7 +1560,8 @@ public class TimeGraphViewer implements ITimeDataProvider2, SelectionListener { } /** - * @param filter The filter object to be attached to the view + * @param filter + * The filter object to be attached to the view * @since 2.0 */ public void removeFilter(ViewerFilter filter) { 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 0edbdf775e..8b5b826629 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 @@ -138,6 +138,7 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe private final Cursor fZoomCursor = Display.getDefault().getSystemCursor(SWT.CURSOR_SIZEWE); private final List fFilters = new ArrayList(); private MenuDetectEvent fPendingMenuDetectEvent = null; + private boolean fHideArrows = false; private int fBorderWidth = 0; private int fHeaderHeight = 0; @@ -902,6 +903,17 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe fTimeProvider.setStartFinishTimeNotify(time0, time1); } + /** + * Hide arrows + * + * @param hideArrows true to hide arrows + * + * @since 2.1 + */ + public void hideArrows(boolean hideArrows) { + fHideArrows = hideArrows; + } + /** * Return the currently selected trace * @@ -1379,6 +1391,9 @@ public class TimeGraphControl extends TimeGraphBaseControl implements FocusListe */ public void drawLinks(Rectangle bounds, ITimeDataProvider timeProvider, List links, int nameSpace, GC gc) { + if (fHideArrows) { + return; + } for (ILinkEvent event : links) { drawLink(event, bounds, timeProvider, nameSpace, gc); } -- 2.34.1