import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.events.MenuDetectEvent;
+import org.eclipse.swt.events.MenuDetectListener;
+import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
-import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.Attributes;
-import org.eclipse.tracecompass.analysis.os.linux.core.kernelanalysis.KernelAnalysisModule;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.TreeItem;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.Attributes;
+import org.eclipse.tracecompass.analysis.os.linux.core.kernel.KernelAnalysisModule;
import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Activator;
import org.eclipse.tracecompass.internal.analysis.os.linux.ui.Messages;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.actions.FollowThreadAction;
+import org.eclipse.tracecompass.internal.analysis.os.linux.ui.views.controlflow.ControlFlowColumnComparators;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
import org.eclipse.tracecompass.tmf.ui.views.timegraph.AbstractStateSystemTimeGraphView;
+import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.TimeGraphCombo;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.Resolution;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
+import com.google.common.collect.ImmutableList;
+
/**
* The Control Flow view main object
*
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
-
/**
* View ID.
*/
// Timeout between updates in the build thread in ms
private static final long BUILD_UPDATE_TIMEOUT = 500;
+ private static final Comparator<ITimeGraphEntry>[] COLUMN_COMPARATORS;
+
+ private static final int INITIAL_SORT_COLUMN_INDEX = 3;
+
+ static {
+ ImmutableList.Builder<Comparator<ITimeGraphEntry>> builder = ImmutableList.builder();
+ builder.add(ControlFlowColumnComparators.PROCESS_NAME_COLUMN_COMPARATOR)
+ .add(ControlFlowColumnComparators.TID_COLUMN_COMPARATOR)
+ .add(ControlFlowColumnComparators.PTID_COLUMN_COMPARATOR)
+ .add(ControlFlowColumnComparators.BIRTH_TIME_COLUMN_COMPARATOR)
+ .add(ControlFlowColumnComparators.TRACE_COLUMN_COMPARATOR);
+ List<Comparator<ITimeGraphEntry>> l = builder.build();
+ COLUMN_COMPARATORS = l.toArray(new Comparator[l.size()]);
+ }
+
+ private MenuManager fMenuMgr;
+
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
*/
public ControlFlowView() {
super(ID, new ControlFlowPresentationProvider());
- setTreeColumns(COLUMN_NAMES);
+ setTreeColumns(COLUMN_NAMES, COLUMN_COMPARATORS, INITIAL_SORT_COLUMN_INDEX);
setTreeLabelProvider(new ControlFlowTreeLabelProvider());
setFilterColumns(FILTER_COLUMN_NAMES);
setFilterLabelProvider(new ControlFlowFilterLabelProvider());
- setEntryComparator(new ControlFlowEntryComparator());
+ setEntryComparator(ControlFlowColumnComparators.BIRTH_TIME_COLUMN_COMPARATOR);
}
@Override
// add "Uncheck inactive" Button to TimeGraphFilterDialog
super.getTimeGraphCombo().addTimeGraphFilterUncheckInactiveButton(
new ControlFlowCheckActiveProvider(Messages.ControlFlowView_uncheckInactiveLabel, Messages.ControlFlowView_uncheckInactiveToolTip));
+ createContextMenu();
+ }
+
+ private void createContextMenu() {
+ fMenuMgr = new MenuManager();
+ final TimeGraphCombo timeGraphCombo = getTimeGraphCombo();
+ TreeViewer treeViewer = timeGraphCombo.getTreeViewer();
+ Control control = treeViewer.getControl();
+ Menu menu = fMenuMgr.createContextMenu(control);
+ control.setMenu(menu);
+ control.addMenuDetectListener(new MenuDetectListener() {
+ @Override
+ public void menuDetected(MenuDetectEvent event) {
+ fMenuMgr.removeAll();
+ Point point = control.toControl(event.x, event.y);
+ // this is super important, it makes zoom still work. Do not try
+ // to extend to the time graph area.
+ TreeItem item = treeViewer.getTree().getItem(point);
+
+ if (item.getData() instanceof ControlFlowEntry) {
+ ControlFlowEntry entry = (ControlFlowEntry) item.getData();
+ fMenuMgr.add(new FollowThreadAction(ControlFlowView.this, entry.getName(), entry.getThreadId(), entry.getTrace()));
+ }
+ }
+ });
+
}
@Override
return Messages.ControlFlowView_previousProcessActionToolTipText;
}
- private static class ControlFlowEntryComparator implements Comparator<ITimeGraphEntry> {
-
- @Override
- public int compare(ITimeGraphEntry o1, ITimeGraphEntry o2) {
-
- int result = 0;
-
- if ((o1 instanceof ControlFlowEntry) && (o2 instanceof ControlFlowEntry)) {
- ControlFlowEntry entry1 = (ControlFlowEntry) o1;
- ControlFlowEntry entry2 = (ControlFlowEntry) o2;
- result = entry1.getTrace().getStartTime().compareTo(entry2.getTrace().getStartTime());
- if (result == 0) {
- result = entry1.getTrace().getName().compareTo(entry2.getTrace().getName());
- }
- if (result == 0) {
- result = entry1.getThreadId() < entry2.getThreadId() ? -1 : entry1.getThreadId() > entry2.getThreadId() ? 1 : 0;
- }
- }
-
- if (result == 0) {
- result = o1.getStartTime() < o2.getStartTime() ? -1 : o1.getStartTime() > o2.getStartTime() ? 1 : 0;
- }
-
- return result;
- }
- }
-
/**
* @author gbastien
*
if (thread > 0) {
break;
}
- if (trace == null) {
- continue;
- }
ITmfStateSystem ssq = TmfStateSystemAnalysisModule.getStateSystem(trace, KernelAnalysisModule.ID);
if (ssq == null) {
continue;
return list;
}
for (ITmfTrace trace : TmfTraceManager.getTraceSet(getTrace())) {
- if (trace == null) {
- continue;
- }
List<Integer> currentThreadQuarks = ss.getQuarks(Attributes.CPUS, "*", Attributes.CURRENT_THREAD); //$NON-NLS-1$
for (int currentThreadQuark : currentThreadQuarks) {
if (currentThreadQuark >= fullStates.get(0).size()) {