diff options
author | Jean-Christian Kouame | 2018-06-08 15:16:33 +0000 |
---|---|---|
committer | Jean-Christian Kouame | 2018-08-07 17:27:36 +0000 |
commit | ba11f8207e1a02b422d02dd5f79809ffd4a5ce3b (patch) | |
tree | ddc908c6e501bcb4e72dc86fb4c2cc010d36cbde | |
parent | ea61d22bd2f83a94fb5c5655dc5c08ab37cb9471 (diff) | |
download | org.eclipse.tracecompass-ba11f8207e1a02b422d02dd5f79809ffd4a5ce3b.tar.gz org.eclipse.tracecompass-ba11f8207e1a02b422d02dd5f79809ffd4a5ce3b.tar.xz org.eclipse.tracecompass-ba11f8207e1a02b422d02dd5f79809ffd4a5ce3b.zip |
tmf.ui: add follow thread filter in resources view
Add a context menu to track the selected thread in the resources view.
Add support for multiple regex filter strings.
Change-Id: Ic353648f1cd6984aef28a38e99b19a194747348a
Signed-off-by: Alexis-Maurer Fortin <alexis-maurer.fortin@polymtl.ca>
Signed-off-by: Guillaume Champagne <guillaume.champagne@polymtl.ca>
Signed-off-by: Hugo Genesse <hugo.genesse@polymtl.ca>
Signed-off-by: Pierre-Yves Lajoie<pierre-yves.lajoie@polymtl.ca>
Signed-off-by: Eva Terriault <eva.terriault@polymtl.ca>
Signed-off-by: Jean-Christian Kouame <jean-christian.kouame@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/120603
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: CI Bot
5 files changed, 192 insertions, 1 deletions
diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/FollowThreadAction.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/FollowThreadAction.java index 730c39bfd3..4d3b8148d0 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/FollowThreadAction.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/FollowThreadAction.java @@ -27,6 +27,7 @@ import org.eclipse.tracecompass.tmf.ui.views.TmfView; @NonNullByDefault public class FollowThreadAction extends Action { + private static final String TID = " TID "; //$NON-NLS-1$ private final TmfView fView; private final HostThread fHostThread; private final @Nullable String fThreadName; @@ -68,7 +69,7 @@ public class FollowThreadAction extends Action { @Override public String getText() { if (fThreadName == null) { - return Messages.FollowThreadAction_follow + ' ' + fHostThread.getTid(); + return Messages.FollowThreadAction_follow + TID + fHostThread.getTid(); } return Messages.FollowThreadAction_follow + ' ' + fThreadName + '/' + fHostThread.getTid(); } diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/Messages.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/Messages.java index 85278073cc..c8d29d01b2 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/Messages.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/Messages.java @@ -23,6 +23,10 @@ public class Messages extends NLS { */ public static String FollowThreadAction_follow; /** + * Unfollow message + */ + public static String FollowThreadAction_unfollow; + /** * Follow CPU message */ public static String CpuSelectionAction_followCpu; diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/UnfollowThreadAction.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/UnfollowThreadAction.java new file mode 100644 index 0000000000..bd180aa889 --- /dev/null +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/UnfollowThreadAction.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2018 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 + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jface.action.Action; +import org.eclipse.tracecompass.analysis.os.linux.core.model.HostThread; +import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfThreadSelectedSignal; +import org.eclipse.tracecompass.tmf.ui.views.TmfView; + +/** + * Follow Thread Action, this action broadcasts a + * {@link TmfThreadSelectedSignal} when run, it sends a thread id and a trace to + * the signal. + * + * @author Matthew Khouzam + */ +@NonNullByDefault +public class UnfollowThreadAction extends Action { + + private final TmfView fView; + + /** + * Constructor + * + * @param source + * the view that is generating the signal, but also shall broadcast + * it + */ + public UnfollowThreadAction(TmfView source) { + fView = source; + } + + @Override + public String getText() { + return Messages.FollowThreadAction_unfollow; + } + + @Override + public void run() { + fView.broadcast(new TmfThreadSelectedSignal(fView, new HostThread("", -1))); //$NON-NLS-1$ + super.run(); + } + +} diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/messages.properties b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/messages.properties index 31104f8d44..0ad0ed6254 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/messages.properties +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/actions/messages.properties @@ -8,5 +8,6 @@ ############################################################################### FollowThreadAction_follow=Follow +FollowThreadAction_unfollow=Unfollow CpuSelectionAction_followCpu=Follow CPU CpuSelectionAction_unfollowCpu=Unfollow CPU diff --git a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java index 86868ced7b..ea9c378733 100644 --- a/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java +++ b/analysis/org.eclipse.tracecompass.analysis.os.linux.ui/src/org/eclipse/tracecompass/internal/analysis/os/linux/ui/views/resources/ResourcesView.java @@ -19,16 +19,24 @@ import java.util.List; import java.util.function.Function; import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfCpuSelectedSignal; +import org.eclipse.tracecompass.analysis.os.linux.core.signals.TmfThreadSelectedSignal; import org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus.ResourcesEntryModel; import org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus.ResourcesEntryModel.Type; import org.eclipse.tracecompass.internal.analysis.os.linux.core.resourcesstatus.ResourcesStatusDataProvider; import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages; import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowCpuAction; +import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowThreadAction; import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.UnfollowCpuAction; +import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.UnfollowThreadAction; +import org.eclipse.tracecompass.tmf.core.model.timegraph.IFilterProperty; import org.eclipse.tracecompass.tmf.core.model.timegraph.ITimeGraphEntryModel; import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler; import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; @@ -36,7 +44,13 @@ import org.eclipse.tracecompass.tmf.core.trace.TmfTraceContext; import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager; import org.eclipse.tracecompass.tmf.ui.views.timegraph.BaseDataProviderTimeGraphView; import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NamedTimeEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent; import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl; +import org.eclipse.ui.IWorkbenchActionConstants; + +import com.google.common.collect.Multimap; /** * Main implementation for the LTTng 2.0 kernel Resource view @@ -51,6 +65,15 @@ public class ResourcesView extends BaseDataProviderTimeGraphView { /** ID of the followed CPU in the map data in {@link TmfTraceContext} */ public static final @NonNull String RESOURCES_FOLLOW_CPU = ID + ".FOLLOW_CPU"; //$NON-NLS-1$ + /** + * ID of the followed Current Thread in the map data in {@link TmfTraceContext} + */ + public static final @NonNull String RESOURCES_FOLLOW_CURRENT_THREAD = ID + ".FOLLOW_CURRENT_THREAD"; //$NON-NLS-1$ + + private static final String EMPTY_STRING = ""; //$NON-NLS-1$ + + private String fFollowedThread = EMPTY_STRING; + private static final String[] FILTER_COLUMN_NAMES = new String[] { Messages.ResourcesView_stateTypeName }; @@ -99,6 +122,45 @@ public class ResourcesView extends BaseDataProviderTimeGraphView { } } + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + createTimeEventContextMenu(); + } + + private void createTimeEventContextMenu() { + MenuManager eventMenuManager = new MenuManager(); + eventMenuManager.setRemoveAllWhenShown(true); + TimeGraphControl timeGraphControl = getTimeGraphViewer().getTimeGraphControl(); + final Menu timeEventMenu = eventMenuManager.createContextMenu(timeGraphControl); + + timeGraphControl.addTimeGraphEntryMenuListener(event -> { + /* + * The TimeGraphControl will call the TimeGraphEntryMenuListener + * before the TimeEventMenuListener. We need to clear the menu + * for the case the selection was done on the namespace where + * the time event listener below won't be called afterwards. + */ + timeGraphControl.setMenu(null); + event.doit = false; + }); + timeGraphControl.addTimeEventMenuListener(event -> { + Menu menu = timeEventMenu; + if (event.data instanceof TimeEvent) { + timeGraphControl.setMenu(menu); + return; + } + timeGraphControl.setMenu(null); + event.doit = false; + }); + + eventMenuManager.addMenuListener(manager -> { + fillTimeEventContextMenu(eventMenuManager); + eventMenuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); + }); + getSite().registerContextMenu(eventMenuManager, getTimeGraphViewer().getSelectionProvider()); + } + /** * @since 2.0 */ @@ -129,6 +191,35 @@ public class ResourcesView extends BaseDataProviderTimeGraphView { } } + /** + * Fill context menu + * + * @param menuManager + * a menuManager to fill + */ + protected void fillTimeEventContextMenu(@NonNull IMenuManager menuManager) { + ISelection selection = getSite().getSelectionProvider().getSelection(); + if (selection instanceof IStructuredSelection) { + IStructuredSelection sSel = (IStructuredSelection) selection; + if (sSel.getFirstElement() instanceof TimeGraphEntry) { + TimeGraphEntry resourcesEntry = (TimeGraphEntry) sSel.getFirstElement(); + ITimeGraphEntryModel model = resourcesEntry.getModel(); + if (sSel.toArray()[1] instanceof NamedTimeEvent && ((ResourcesEntryModel) model).getType() == Type.CURRENT_THREAD) { + ITmfTrace trace = getTrace(resourcesEntry); + NamedTimeEvent event = (NamedTimeEvent) sSel.toArray()[1]; + TmfTraceContext ctx = TmfTraceManager.getInstance().getCurrentTraceContext(); + Integer data = (Integer) ctx.getData(RESOURCES_FOLLOW_CURRENT_THREAD); + int tid = data != null ? data.intValue() : -1; + if (tid >= 0) { + menuManager.add(new UnfollowThreadAction(ResourcesView.this)); + } else { + menuManager.add(new FollowThreadAction(ResourcesView.this, null, event.getValue(), trace)); + } + } + } + } + } + private static class ResourcesFilterLabelProvider extends TreeLabelProvider { @Override public String getColumnText(Object element, int columnIndex) { @@ -163,6 +254,25 @@ public class ResourcesView extends BaseDataProviderTimeGraphView { return Messages.ResourcesView_previousResourceActionToolTipText; } + private void setFollowedThread(String regex) { + fFollowedThread = regex; + } + + private void removeFollowedThread() { + fFollowedThread = EMPTY_STRING; + } + + @Override + protected @NonNull Multimap<@NonNull Integer, @NonNull String> getRegexes() { + Multimap<@NonNull Integer, @NonNull String> regexes = super.getRegexes(); + if (!fFollowedThread.isEmpty()) { + regexes.put(IFilterProperty.BOUND, fFollowedThread); + } else { + regexes.removeAll(IFilterProperty.BOUND); + } + return regexes; + } + /** * Signal handler for a cpu selected signal. * @@ -181,4 +291,27 @@ public class ResourcesView extends BaseDataProviderTimeGraphView { builder -> builder.setData(RESOURCES_FOLLOW_CPU, data)); } + /** + * Signal handler for a thread selected signal. + * + * @param signal + * the thread selected signal + * @since 2.0 + */ + @TmfSignalHandler + public void listenToCurrentThread(TmfThreadSelectedSignal signal) { + int data = signal.getThreadId() >= 0 ? signal.getThreadId() : -1; + ITmfTrace trace = getTrace(); + if (trace == null) { + return; + } + TmfTraceManager.getInstance().updateTraceContext(trace, + builder -> builder.setData(RESOURCES_FOLLOW_CURRENT_THREAD, data)); + if (data >= 0) { + setFollowedThread("Current_thread==" + ((Integer) data).toString() + " || TID==" + ((Integer) data).toString()); //$NON-NLS-1$ //$NON-NLS-2$ + } else { + removeFollowedThread(); + } + restartZoomThread(); + } } |