X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=org.eclipse.linuxtools.tmf.ui%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Ftmf%2Fui%2Fviewers%2Fevents%2FTmfEventsTable.java;h=6523a7cf4b294acd62b48f16a0cb9ac568960733;hb=fbdee51bae97d04fb50bec47da228e74672154ca;hp=6ee25c6ee091bac32e0545689607a278f6c73aa6;hpb=3bd46eefe5f348d628cf62f6a6538508375fe2f6;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java index 6ee25c6ee0..6523a7cf4b 100644 --- a/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java +++ b/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/viewers/events/TmfEventsTable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2011, 2012 Ericsson + * Copyright (c) 2010, 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 @@ -7,25 +7,33 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Francois Chouinard - Initial API and implementation - * Patrick Tasse - Factored out from events view - * Francois Chouinard - Replaced Table by TmfVirtualTable - * Patrick Tasse - Filter implementation (inspired by www.eclipse.org/mat) + * Francois Chouinard - Initial API and implementation, replaced Table by TmfVirtualTable + * Patrick Tasse - Factored out from events view, + * Filter implementation (inspired by www.eclipse.org/mat) * Ansgar Radermacher - Support navigation to model URIs (Bug 396956) + * Bernd Hufmann - Updated call site and model URI implementation + * Alexandre Montplaisir - Update to new column API *******************************************************************************/ package org.eclipse.linuxtools.tmf.ui.viewers.events; import java.io.FileNotFoundException; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import org.eclipse.core.commands.Command; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.core.commands.NotEnabledException; +import org.eclipse.core.commands.NotHandledException; +import org.eclipse.core.commands.ParameterizedCommand; +import org.eclipse.core.commands.common.NotDefinedException; +import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; @@ -41,10 +49,12 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EValidator; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.InputDialog; @@ -62,41 +72,46 @@ import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.window.Window; +import org.eclipse.linuxtools.internal.tmf.core.filter.TmfCollapseFilter; import org.eclipse.linuxtools.internal.tmf.ui.Activator; import org.eclipse.linuxtools.internal.tmf.ui.Messages; +import org.eclipse.linuxtools.internal.tmf.ui.commands.ExportToTextCommandHandler; import org.eclipse.linuxtools.internal.tmf.ui.dialogs.MultiLineInputDialog; -import org.eclipse.linuxtools.tmf.core.component.ITmfDataProvider; +import org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider; import org.eclipse.linuxtools.tmf.core.component.TmfComponent; -import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfConstants; -import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfCallsite; -import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEventField; -import org.eclipse.linuxtools.tmf.core.event.TmfEventField; +import org.eclipse.linuxtools.tmf.core.event.collapse.ITmfCollapsibleEvent; +import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfCallsite; +import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfModelLookup; +import org.eclipse.linuxtools.tmf.core.event.lookup.ITmfSourceLookup; import org.eclipse.linuxtools.tmf.core.filter.ITmfFilter; import org.eclipse.linuxtools.tmf.core.filter.model.ITmfFilterTreeNode; import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterAndNode; import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterMatchesNode; import org.eclipse.linuxtools.tmf.core.filter.model.TmfFilterNode; -import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType; -import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest; +import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest.ExecutionType; +import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; import org.eclipse.linuxtools.tmf.core.signal.TmfEventFilterAppliedSignal; import org.eclipse.linuxtools.tmf.core.signal.TmfEventSearchAppliedSignal; +import org.eclipse.linuxtools.tmf.core.signal.TmfEventSelectedSignal; import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal; import org.eclipse.linuxtools.tmf.core.signal.TmfTraceUpdatedSignal; import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange; import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp; import org.eclipse.linuxtools.tmf.core.trace.ITmfContext; -import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation; import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; +import org.eclipse.linuxtools.tmf.core.trace.TmfTraceManager; +import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation; import org.eclipse.linuxtools.tmf.ui.viewers.events.TmfEventsCache.CachedEvent; +import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableColumn; +import org.eclipse.linuxtools.tmf.ui.viewers.events.columns.TmfEventTableFieldColumn; import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting; import org.eclipse.linuxtools.tmf.ui.views.colors.ColorSettingsManager; import org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener; import org.eclipse.linuxtools.tmf.ui.views.filter.FilterManager; import org.eclipse.linuxtools.tmf.ui.widgets.rawviewer.TmfRawEventViewer; -import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData; import org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.TmfVirtualTable; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.SashForm; @@ -129,25 +144,44 @@ import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.dialogs.ListDialog; +import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.ide.IGotoMarker; import org.eclipse.ui.themes.ColorUtil; +import com.google.common.base.Joiner; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Multimap; + /** * The generic TMF Events table * * This is a view that will list events that are read from a trace. * - * @version 1.0 * @author Francois Chouinard * @author Patrick Tasse * @since 2.0 */ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorSettingsListener, ISelectionProvider { + /** + * Empty string array, used by {@link #getItemStrings}. + * @since 3.0 + */ + protected static final @NonNull String[] EMPTY_STRING_ARRAY = new String[0]; + + /** + * Empty string + * @since 3.1 + */ + protected static final @NonNull String EMPTY_STRING = ""; //$NON-NLS-1$ + + private static final boolean IS_LINUX = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$ + private static final Image BOOKMARK_IMAGE = Activator.getDefault().getImageFromPath( "icons/elcl16/bookmark_obj.gif"); //$NON-NLS-1$ private static final Image SEARCH_IMAGE = Activator.getDefault().getImageFromPath("icons/elcl16/search.gif"); //$NON-NLS-1$ @@ -162,6 +196,23 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS private static final String FILTER_HINT = Messages.TmfEventsTable_FilterHint; private static final int MAX_CACHE_SIZE = 1000; + private static final int MARGIN_COLUMN_INDEX = 0; + private static final int FILTER_SUMMARY_INDEX = 1; + private static final int EVENT_COLUMNS_START_INDEX = MARGIN_COLUMN_INDEX + 1; + + /** + * Default set of columns to use for trace types that do not specify + * anything + * @since 3.2 + */ + public static final Collection DEFAULT_COLUMNS = ImmutableList.of( + TmfEventTableColumn.BaseColumns.TIMESTAMP, + TmfEventTableColumn.BaseColumns.SOURCE, + TmfEventTableColumn.BaseColumns.EVENT_TYPE, + TmfEventTableColumn.BaseColumns.REFERENCE, + TmfEventTableColumn.BaseColumns.CONTENTS + ); + /** * The events table search/filter keys * @@ -181,7 +232,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS /** Filter object */ String FILTER_OBJ = "$fltr_obj"; //$NON-NLS-1$ - /** Timestamp*/ + /** Timestamp */ String TIMESTAMP = "$time"; //$NON-NLS-1$ /** Rank */ @@ -224,9 +275,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS private SashForm fSashForm; private TmfRawEventViewer fRawViewer; private ITmfTrace fTrace; - private boolean fPackDone = false; + volatile private boolean fPackDone = false; private HeaderState fHeaderState = HeaderState.SEARCH; private long fSelectedRank = 0; + private ITmfTimestamp fSelectedBeginTimestamp = null; + private IStatusLineManager fStatusLineManager = null; // Filter data private long fFilterMatchCount; @@ -245,7 +298,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS private ListenerList selectionChangedListeners = new ListenerList(); // Bookmark map - private Map fBookmarksMap = new HashMap(); + private Multimap fBookmarksMap = HashMultimap.create(); private IFile fBookmarksFile; private long fPendingGotoRank = -1; @@ -255,14 +308,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS private Color fGreenColor; private Font fBoldFont; - // Table column names - private static final String[] COLUMN_NAMES = new String[] { Messages.TmfEventsTable_TimestampColumnHeader, - Messages.TmfEventsTable_SourceColumnHeader, Messages.TmfEventsTable_TypeColumnHeader, - Messages.TmfEventsTable_ReferenceColumnHeader, Messages.TmfEventsTable_ContentColumnHeader }; - - private static final ColumnData[] COLUMN_DATA = new ColumnData[] { new ColumnData(COLUMN_NAMES[0], 100, SWT.LEFT), - new ColumnData(COLUMN_NAMES[1], 100, SWT.LEFT), new ColumnData(COLUMN_NAMES[2], 100, SWT.LEFT), - new ColumnData(COLUMN_NAMES[3], 100, SWT.LEFT), new ColumnData(COLUMN_NAMES[4], 100, SWT.LEFT) }; + private final List fColumns = new LinkedList<>(); // Event cache private final TmfEventsCache fCache; @@ -278,7 +324,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS // ------------------------------------------------------------------------ /** - * Basic constructor, will use default column data. + * Basic constructor, using the default set of columns * * @param parent * The parent composite UI object @@ -286,20 +332,63 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS * The size of the event table cache */ public TmfEventsTable(final Composite parent, final int cacheSize) { - this(parent, cacheSize, COLUMN_DATA); + this(parent, cacheSize, DEFAULT_COLUMNS); } /** - * Advanced constructor, where we also define which column data to use. + * Legacy constructor, using ColumnData to define columns * * @param parent * The parent composite UI object * @param cacheSize * The size of the event table cache * @param columnData - * The column data to use for this table + * Unused + * @deprecated Deprecated constructor, use + * {@link #TmfEventsTable(Composite, int, Collection)} + */ + @Deprecated + public TmfEventsTable(final Composite parent, int cacheSize, + final org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { + /* + * We'll do a "best-effort" to keep trace types still using this API to + * keep working, by defining a TmfEventTableFieldColumn for each + * ColumnData they passed. + */ + this(parent, cacheSize, convertFromColumnData(columnData)); + } + + @Deprecated + private static Collection convertFromColumnData( + org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData[] columnData) { + + ImmutableList.Builder builder = new ImmutableList.Builder<>(); + for (org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData col : columnData) { + String header = col.header; + if (header != null) { + builder.add(new TmfEventTableFieldColumn(header)); + } + } + return builder.build(); + } + + /** + * Standard constructor, where we define which columns to use. + * + * @param parent + * The parent composite UI object + * @param cacheSize + * The size of the event table cache + * @param columns + * The columns to use in this table. + *

+ * The iteration order of this collection will correspond to the + * initial ordering of this series of columns in the table. + *

+ * @since 3.1 */ - public TmfEventsTable(final Composite parent, int cacheSize, final ColumnData[] columnData) { + public TmfEventsTable(final Composite parent, int cacheSize, + Collection columns) { super("TmfEventsTable"); //$NON-NLS-1$ fComposite = new Composite(parent, SWT.NONE); @@ -313,7 +402,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // Create a virtual table - final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE | SWT.FULL_SELECTION; + final int style = SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION; fTable = new TmfVirtualTable(fSashForm, style); // Set the table layout @@ -324,16 +413,24 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fTable.setHeaderVisible(true); fTable.setLinesVisible(true); - // Set the columns - setColumnHeaders(columnData); + // Setup the columns + if (columns != null) { + fColumns.addAll(columns); + } + + TmfMarginColumn collapseCol = new TmfMarginColumn(); + fColumns.add(MARGIN_COLUMN_INDEX, collapseCol); - // Set the default column field ids if this is not a subclass - if (Arrays.equals(columnData, COLUMN_DATA)) { - fTable.getColumns()[0].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_TIMESTAMP); - fTable.getColumns()[1].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_SOURCE); - fTable.getColumns()[2].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_TYPE); - fTable.getColumns()[3].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_REFERENCE); - fTable.getColumns()[4].setData(Key.FIELD_ID, ITmfEvent.EVENT_FIELD_CONTENT); + // Create the UI columns in the table + for (TmfEventTableColumn col : fColumns) { + TableColumn column = fTable.newTableColumn(SWT.LEFT); + column.setText(col.getHeaderName()); + column.setToolTipText(col.getHeaderTooltip()); + column.setData(Key.FIELD_ID, col.getFilterFieldId()); + column.pack(); + if (col instanceof TmfMarginColumn) { + column.setResizable(false); + } } // Set the frozen row for header row @@ -346,21 +443,43 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fTable.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(final SelectionEvent e) { - final TableItem[] selection = fTable.getSelection(); - if (selection.length > 0) { - final TableItem selectedTableItem = selection[0]; - if (selectedTableItem != null) { - if (selectedTableItem.getData(Key.RANK) instanceof Long) { - fSelectedRank = (Long) selectedTableItem.getData(Key.RANK); - fRawViewer.selectAndReveal((Long) selectedTableItem.getData(Key.RANK)); + if (e.item == null) { + return; + } + updateStatusLine(null); + if (fTable.getSelectionIndices().length > 0) { + if (e.item.getData(Key.RANK) instanceof Long) { + fSelectedRank = (Long) e.item.getData(Key.RANK); + fRawViewer.selectAndReveal((Long) e.item.getData(Key.RANK)); + } + if (e.item.getData(Key.TIMESTAMP) instanceof ITmfTimestamp) { + final ITmfTimestamp ts = (ITmfTimestamp) e.item.getData(Key.TIMESTAMP); + if (fTable.getSelectionIndices().length == 1) { + fSelectedBeginTimestamp = ts; } - if (selectedTableItem.getData(Key.TIMESTAMP) instanceof TmfTimestamp) { - final TmfTimestamp ts = (TmfTimestamp) selectedTableItem.getData(Key.TIMESTAMP); - broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts)); + if (fSelectedBeginTimestamp != null) { + if (fSelectedBeginTimestamp.compareTo(ts) <= 0) { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, fSelectedBeginTimestamp, ts)); + if (fTable.getSelectionIndices().length == 2) { + updateStatusLine(ts.getDelta(fSelectedBeginTimestamp)); + } + } else { + broadcast(new TmfTimeSynchSignal(TmfEventsTable.this, ts, fSelectedBeginTimestamp)); + updateStatusLine(fSelectedBeginTimestamp.getDelta(ts)); + } + } + } else { + if (fTable.getSelectionIndices().length == 1) { + fSelectedBeginTimestamp = null; } } } - fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, getSelection())); + if (e.item.getData() instanceof ITmfEvent) { + broadcast(new TmfEventSelectedSignal(TmfEventsTable.this, (ITmfEvent) e.item.getData())); + fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, new StructuredSelection(e.item.getData()))); + } else { + fireSelectionChanged(new SelectionChangedEvent(TmfEventsTable.this, StructuredSelection.EMPTY)); + } } }); @@ -392,7 +511,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS final CachedEvent cachedEvent = fCache.getEvent(index); if (cachedEvent != null) { - setItemData(item, cachedEvent.event, cachedEvent.rank); + setItemData(item, cachedEvent, cachedEvent.rank); return; } @@ -452,7 +571,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS layout.marginWidth = 2; tooltipShell.setLayout(layout); final Label label = new Label(tooltipShell, SWT.WRAP); - String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : ""); //$NON-NLS-1$ //$NON-NLS-2$ + String text = rank.toString() + (tooltipText != null ? ": " + tooltipText : EMPTY_STRING); //$NON-NLS-1$ label.setForeground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); label.setBackground(PlatformUI.getWorkbench().getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); label.setText(text); @@ -465,7 +584,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS * the method toDisplay() expects coordinates relative to an origin that includes the table header. */ int y = event.y; - if (System.getProperty("os.name").contains("Linux")) { //$NON-NLS-1$ //$NON-NLS-2$ + if (IS_LINUX) { y += fTable.getHeaderHeight(); } Point pt = fTable.toDisplay(event.x, y); @@ -519,6 +638,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } fTable.setSelection(index + 1); // +1 for header row fSelectedRank = rank; + updateStatusLine(null); } else if (e.data instanceof ITmfLocation) { // DOES NOT WORK: rank undefined in context from seekLocation() // ITmfLocation location = (ITmfLocation) e.data; @@ -544,6 +664,10 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS createPopupMenu(); } + // ------------------------------------------------------------------------ + // Operations + // ------------------------------------------------------------------------ + /** * Create a pop-up menu. */ @@ -570,7 +694,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fRawViewer.setVisible(true); fSashForm.layout(); final int index = fTable.getSelectionIndex(); - if (index >= +1) { + if (index >= 1) { fRawViewer.selectAndReveal(index - 1); } } @@ -584,7 +708,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } }; - final IAction openCallsiteAction = new Action(Messages.TmfEventsTable_OpenCallsiteActionText) { + final IAction openCallsiteAction = new Action(Messages.TmfEventsTable_OpenSourceCodeActionText) { @Override public void run() { final TableItem items[] = fTable.getSelection(); @@ -594,17 +718,17 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS final TableItem item = items[0]; final Object data = item.getData(); - if (data instanceof CtfTmfEvent) { - CtfTmfEvent event = (CtfTmfEvent) data; - CtfTmfCallsite cs = event.getCallsite(); + if (data instanceof ITmfSourceLookup) { + ITmfSourceLookup event = (ITmfSourceLookup) data; + ITmfCallsite cs = event.getCallsite(); if (cs == null || cs.getFileName() == null) { return; } IMarker marker = null; try { String fileName = cs.getFileName(); - final String trimmedPath = fileName.replaceAll("\\.\\./", ""); //$NON-NLS-1$ //$NON-NLS-2$ - final ArrayList files = new ArrayList(); + final String trimmedPath = fileName.replaceAll("\\.\\./", EMPTY_STRING); //$NON-NLS-1$ + final ArrayList files = new ArrayList<>(); ResourcesPlugin.getWorkspace().getRoot().accept(new IResourceVisitor() { @Override public boolean visit(IResource resource) throws CoreException { @@ -625,8 +749,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } }); dialog.setInput(files); - dialog.setTitle(Messages.TmfEventsTable_OpenCallsiteSelectFileDialogTitle); - dialog.setMessage(Messages.TmfEventsTable_OpenCallsiteSelectFileDialogTitle + '\n' + cs.toString()); + dialog.setTitle(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle); + dialog.setMessage(Messages.TmfEventsTable_OpenSourceCodeSelectFileDialogTitle + '\n' + cs.toString()); dialog.open(); Object[] result = dialog.getResult(); if (result != null && result.length > 0) { @@ -641,14 +765,10 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), marker); marker.delete(); } else if (files.size() == 0){ - displayException(new FileNotFoundException('\'' + cs.toString() + '\'' + '\n' + Messages.TmfEventsTable_OpenCallsiteNotFound)); + displayException(new FileNotFoundException('\'' + cs.toString() + '\'' + '\n' + Messages.TmfEventsTable_OpenSourceCodeNotFound)); } - } catch (PartInitException e) { - // TODO Auto-generated catch block - e.printStackTrace(); } catch (CoreException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + displayException(e); } } } @@ -665,8 +785,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS final TableItem item = items[0]; final Object eventData = item.getData(); - if (eventData instanceof CtfTmfEvent) { - String modelURI = ((CtfTmfEvent) eventData).getCustomAttribute(CtfConstants.MODEL_URI_KEY); + if (eventData instanceof ITmfModelLookup) { + String modelURI = ((ITmfModelLookup) eventData).getModelUri(); if (modelURI != null) { IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); @@ -707,6 +827,35 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } }; + final IAction exportToTextAction = new Action(Messages.TmfEventsTable_Export_to_text) { + @Override + public void run() { + IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + IHandlerService handlerService = (IHandlerService) activePage.getActiveEditor().getSite().getService(IHandlerService.class); + ICommandService cmdService = (ICommandService) activePage.getActiveEditor().getSite().getService(ICommandService.class); + try { + HashMap parameters = new HashMap<>(); + Command command = cmdService.getCommand(ExportToTextCommandHandler.COMMAND_ID); + ParameterizedCommand cmd = ParameterizedCommand.generateCommand(command, parameters); + + IEvaluationContext context = handlerService.getCurrentState(); + // Omit the margin column + List exportColumns = fColumns.subList(EVENT_COLUMNS_START_INDEX, fColumns.size()); + context.addVariable(ExportToTextCommandHandler.TMF_EVENT_TABLE_COLUMNS_ID, exportColumns); + + handlerService.executeCommandInContext(cmd, null, context); + } catch (ExecutionException e) { + displayException(e); + } catch (NotDefinedException e) { + displayException(e); + } catch (NotEnabledException e) { + displayException(e); + } catch (NotHandledException e) { + displayException(e); + } + } + }; + final IAction showSearchBarAction = new Action(Messages.TmfEventsTable_ShowSearchBarActionText) { @Override public void run() { @@ -730,10 +879,17 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } }; + final IAction collapseAction = new Action(Messages.TmfEventsTable_CollapseFilterMenuName) { + @Override + public void run() { + applyFilter(new TmfCollapseFilter()); + } + }; + class ToggleBookmarkAction extends Action { - long fRank; + Long fRank; - public ToggleBookmarkAction(final String text, final long rank) { + public ToggleBookmarkAction(final String text, final Long rank) { super(text); fRank = rank; } @@ -788,27 +944,51 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } else if (!fRawViewer.isVisible()) { tablePopupMenu.add(showRawAction); } + tablePopupMenu.add(exportToTextAction); tablePopupMenu.add(new Separator()); if (item != null) { final Object data = item.getData(); - if (data instanceof CtfTmfEvent) { - Separator separator = null; - CtfTmfEvent event = (CtfTmfEvent) data; + Separator separator = null; + if (data instanceof ITmfSourceLookup) { + ITmfSourceLookup event = (ITmfSourceLookup) data; if (event.getCallsite() != null) { tablePopupMenu.add(openCallsiteAction); separator = new Separator(); } - if (event.listCustomAttributes().contains(CtfConstants.MODEL_URI_KEY)) { + } + + if (data instanceof ITmfModelLookup) { + ITmfModelLookup event = (ITmfModelLookup) data; + if (event.getModelUri() != null) { tablePopupMenu.add(openModelAction); separator = new Separator(); } + if (separator != null) { tablePopupMenu.add(separator); } } } + // only show collapse filter if at least one trace can be collapsed + boolean isCollapsible = false; + if (fTrace != null) { + ITmfTrace traces[] = TmfTraceManager.getTraceSet(fTrace); + for (ITmfTrace trace : traces) { + Class eventClass = trace.getEventType(); + isCollapsible = ITmfCollapsibleEvent.class.isAssignableFrom(eventClass); + if (isCollapsible) { + break; + } + } + } + + if (isCollapsible && !(fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter)) { + tablePopupMenu.add(collapseAction); + tablePopupMenu.add(new Separator()); + } + tablePopupMenu.add(clearFiltersAction); final ITmfFilterTreeNode[] savedFilters = FilterManager.getSavedFilters(); if (savedFilters.length > 0) { @@ -887,6 +1067,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fTrace.dispose(); } fResourceManager.dispose(); + fRawViewer.dispose(); super.dispose(); } @@ -911,11 +1092,13 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS /** * @param columnData - * - * FIXME: Add support for column selection + * columnData + * @deprecated The column headers are now set at the constructor, this + * shouldn't be called anymore. */ - protected void setColumnHeaders(final ColumnData[] columnData) { - fTable.setColumnHeaders(columnData); + @Deprecated + protected void setColumnHeaders(final org.eclipse.linuxtools.tmf.ui.widgets.virtualtable.ColumnData [] columnData) { + /* No-op */ } /** @@ -929,26 +1112,28 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS * Which rank this event has in the trace/experiment */ protected void setItemData(final TableItem item, final ITmfEvent event, final long rank) { - final ITmfEventField[] fields = extractItemFields(event); - final String[] content = new String[fields.length]; - for (int i = 0; i < fields.length; i++) { - content[i] = fields[i].getValue() != null ? fields[i].getValue().toString() : ""; //$NON-NLS-1$ - } - item.setText(content); + String[] itemStrings = getItemStrings(fColumns, event); + item.setText(itemStrings); item.setData(event); item.setData(Key.TIMESTAMP, new TmfTimestamp(event.getTimestamp())); item.setData(Key.RANK, rank); - boolean bookmark = false; - final Long markerId = fBookmarksMap.get(rank); - if (markerId != null) { - bookmark = true; + final Collection markerIds = fBookmarksMap.get(rank); + if (!markerIds.isEmpty()) { + Joiner joiner = Joiner.on("\n -").skipNulls(); //$NON-NLS-1$ + List parts = new ArrayList<>(); + if (markerIds.size() > 1) { + parts.add(Messages.TmfEventsTable_MultipleBookmarksToolTip); + } try { - final IMarker marker = fBookmarksFile.findMarker(markerId); - item.setData(Key.BOOKMARK, marker.getAttribute(IMarker.MESSAGE)); - } catch (final CoreException e) { + for (long markerId : markerIds) { + final IMarker marker = fBookmarksFile.findMarker(markerId); + parts.add(marker.getAttribute(IMarker.MESSAGE)); + } + } catch (CoreException e) { displayException(e); } + item.setData(Key.BOOKMARK, joiner.join(parts)); } else { item.setData(Key.BOOKMARK, null); } @@ -974,16 +1159,20 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } if (searchMatch) { - if (bookmark) { + if (!markerIds.isEmpty()) { item.setImage(SEARCH_MATCH_BOOKMARK_IMAGE); } else { item.setImage(SEARCH_MATCH_IMAGE); } - } else if (bookmark) { + } else if (!markerIds.isEmpty()) { item.setImage(BOOKMARK_IMAGE); } else { item.setImage((Image) null); } + + if ((itemStrings[MARGIN_COLUMN_INDEX] != null) && !itemStrings[MARGIN_COLUMN_INDEX].isEmpty()) { + packMarginColumn(); + } } /** @@ -1002,7 +1191,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS txtKey = Key.FILTER_TXT; } item.setForeground(fGrayColor); - for (int i = 0; i < fTable.getColumns().length; i++) { + // Ignore collapse and image column + for (int i = EVENT_COLUMNS_START_INDEX; i < fTable.getColumns().length; i++) { final TableColumn column = fTable.getColumns()[i]; final String filter = (String) column.getData(txtKey); if (filter == null) { @@ -1029,15 +1219,18 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS */ protected void setFilterStatusRowItemData(final TableItem item) { for (int i = 0; i < fTable.getColumns().length; i++) { - if (i == 0) { + if (i == MARGIN_COLUMN_INDEX) { if ((fTrace == null) || (fFilterCheckCount == fTrace.getNbEvents())) { item.setImage(FILTER_IMAGE); } else { item.setImage(STOP_IMAGE); } - item.setText(0, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$ + } + + if (i == FILTER_SUMMARY_INDEX) { + item.setText(FILTER_SUMMARY_INDEX, fFilterMatchCount + "/" + fFilterCheckCount); //$NON-NLS-1$ } else { - item.setText(i, ""); //$NON-NLS-1$ + item.setText(i, EMPTY_STRING); } } item.setData(null); @@ -1082,6 +1275,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } else if (fHeaderState == HeaderState.FILTER) { fHeaderState = HeaderState.SEARCH; } + fTable.setSelection(0); fTable.refresh(); return; } @@ -1130,6 +1324,9 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if (e.character == SWT.CR) { updateHeader(newEditor.getText()); applyHeader(); + + // Set focus on the table so that the next carriage return goes to the next result + TmfEventsTable.this.getTable().setFocus(); } else if (e.character == SWT.ESC) { tableEditor.getEditor().dispose(); } @@ -1360,6 +1557,11 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fTable.setSelection(0); } fireFilterApplied(null); + updateStatusLine(null); + + // Set original width + fTable.getColumns()[MARGIN_COLUMN_INDEX].setWidth(0); + packMarginColumn(); } /** @@ -1367,7 +1569,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS */ protected class FilterThread extends Thread { private final ITmfFilterTreeNode filter; - private TmfDataRequest request; + private TmfEventRequest request; private boolean refreshBusy = false; private boolean refreshPending = false; private final Object syncObj = new Object(); @@ -1392,27 +1594,34 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if (nbRequested <= 0) { return; } - request = new TmfDataRequest(ITmfEvent.class, (int) fFilterCheckCount, - nbRequested, fTrace.getCacheSize(), ExecutionType.BACKGROUND) { + request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, + (int) fFilterCheckCount, nbRequested, ExecutionType.BACKGROUND) { @Override public void handleData(final ITmfEvent event) { super.handleData(event); if (request.isCancelled()) { return; } + boolean refresh = false; if (filter.matches(event)) { final long rank = fFilterCheckCount; final int index = (int) fFilterMatchCount; fFilterMatchCount++; fCache.storeEvent(event, rank, index); - refreshTable(); - } else if ((fFilterCheckCount % 100) == 0) { + refresh = true; + } else { + if (filter instanceof TmfCollapseFilter) { + fCache.updateCollapsedEvent((int) fFilterMatchCount - 1); + } + } + + if (refresh || (fFilterCheckCount % 100) == 0) { refreshTable(); } fFilterCheckCount++; } }; - ((ITmfDataProvider) fTrace).sendRequest(request); + ((ITmfEventProvider) fTrace).sendRequest(request); try { request.waitForCompletion(); } catch (final InterruptedException e) { @@ -1553,7 +1762,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS private int direction; private long rank; private long foundRank = -1; - private TmfDataRequest request; + private TmfEventRequest request; private ITmfTimestamp foundTimestamp = null; /** @@ -1631,7 +1840,8 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if (direction == Direction.BACKWARD) { rank = Math.max(0, rank - fTrace.getCacheSize() + 1); } - request = new TmfDataRequest(ITmfEvent.class, (int) rank, nbRequested, fTrace.getCacheSize(), ExecutionType.BACKGROUND) { + request = new TmfEventRequest(ITmfEvent.class, TmfTimeRange.ETERNITY, + (int) rank, nbRequested, ExecutionType.BACKGROUND) { long currentRank = rank; @Override @@ -1648,7 +1858,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS currentRank++; } }; - ((ITmfDataProvider) fTrace).sendRequest(request); + ((ITmfEventProvider) fTrace).sendRequest(request); try { request.waitForCompletion(); if (request.isCancelled()) { @@ -1711,6 +1921,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS synchronized (fSearchSyncObj) { fSearchThread = null; } + updateStatusLine(null); } }); return Status.OK_STATUS; @@ -1742,53 +1953,92 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if (fPackDone) { return; } - boolean isLinux = System.getProperty("os.name").contains("Linux") ? true : false; //$NON-NLS-1$ //$NON-NLS-2$ - - TableColumn tableColumns[] = fTable.getColumns(); - for (int i = 0; i < tableColumns.length; i++) { - final TableColumn column = tableColumns[i]; - final int headerWidth = column.getWidth(); - column.pack(); - // Workaround for Linux which doesn't consider the image width of - // search/filter row in TableColumn.pack() after having executed - // TableItem.setImage((Image)null) for other rows than search/filter row. - if (isLinux && (i == 0)) { - column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width); + fTable.setRedraw(false); + try { + TableColumn tableColumns[] = fTable.getColumns(); + for (int i = 0; i < tableColumns.length; i++) { + final TableColumn column = tableColumns[i]; + packSingleColumn(i, column); } + } finally { + // Make sure that redraw is always enabled. + fTable.setRedraw(true); + } + fPackDone = true; + } + + + private void packMarginColumn() { + TableColumn[] columns = fTable.getColumns(); + if (columns.length > 0) { + packSingleColumn(0, columns[0]); + } + } + + private void packSingleColumn(int i, final TableColumn column) { + final int headerWidth = column.getWidth(); + column.pack(); + // Workaround for Linux which doesn't consider the image width of + // search/filter row in TableColumn.pack() after having executed + // TableItem.setImage((Image)null) for other rows than search/filter row. + boolean isCollapseFilter = fTable.getData(Key.FILTER_OBJ) instanceof TmfCollapseFilter; + if (IS_LINUX && (i == 0) && isCollapseFilter) { + column.setWidth(column.getWidth() + SEARCH_IMAGE.getBounds().width); + } + + if (column.getWidth() < headerWidth) { + column.setWidth(headerWidth); + } + } + + /** + * Get the array of item strings (e.g., what to display in each cell of the + * table row) corresponding to the columns and trace event passed in + * parameter. The order of the Strings in the returned array will correspond + * to the iteration order of 'columns'. + * + *

+ * To ensure consistent results, make sure only call this within a scope + * synchronized on 'columns'! If the order of 'columns' changes right after + * this method is called, the returned value won't be ordered correctly + * anymore. + */ + private static String[] getItemStrings(List columns, ITmfEvent event) { + if (event == null) { + return EMPTY_STRING_ARRAY; + } + synchronized (columns) { + List itemStrings = new ArrayList<>(columns.size()); + for (TmfEventTableColumn column : columns) { + ITmfEvent passedEvent = event; + if (!(column instanceof TmfMarginColumn) && (event instanceof CachedEvent)) { + // Make sure that the event object from the trace is passed + // to all columns but the TmfMarginColumn + passedEvent = ((CachedEvent) event).event; + } + if (passedEvent == null) { + itemStrings.add(EMPTY_STRING); + } else { + itemStrings.add(column.getItemString(passedEvent)); + } - if (column.getWidth() < headerWidth) { - column.setWidth(headerWidth); } + return itemStrings.toArray(new String[0]); } - fPackDone = true; } /** - * Extract the fields of an event (item in the table). + * Get the contents of the row in the events table corresponding to an + * event. The order of the elements corresponds to the current order of the + * columns. * * @param event - * The event to extract from - * @return The array of fields - * - * FIXME: Add support for column selection + * The event printed in this row + * @return The event row entries + * @since 3.0 */ - protected ITmfEventField[] extractItemFields(final ITmfEvent event) { - ITmfEventField[] fields = new TmfEventField[0]; - if (event != null) { - final String timestamp = event.getTimestamp().toString(); - final String source = event.getSource(); - final String type = event.getType().getName(); - final String reference = event.getReference(); - final String content = event.getContent().toString(); - fields = new TmfEventField[] { - new TmfEventField(ITmfEvent.EVENT_FIELD_TIMESTAMP, timestamp), - new TmfEventField(ITmfEvent.EVENT_FIELD_SOURCE, source), - new TmfEventField(ITmfEvent.EVENT_FIELD_TYPE, type), - new TmfEventField(ITmfEvent.EVENT_FIELD_REFERENCE, reference), - new TmfEventField(ITmfEvent.EVENT_FIELD_CONTENT, content) - }; - } - return fields; + public String[] getItemStrings(ITmfEvent event) { + return getItemStrings(fColumns, event); } /** @@ -1840,6 +2090,30 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS }); } + /** + * Assign the status line manager + * + * @param statusLineManager + * The status line manager, or null to disable status line messages + * @since 2.1 + */ + public void setStatusLineManager(IStatusLineManager statusLineManager) { + if (fStatusLineManager != null && statusLineManager == null) { + fStatusLineManager.setMessage(EMPTY_STRING); + } + fStatusLineManager = statusLineManager; + } + + private void updateStatusLine(ITmfTimestamp delta) { + if (fStatusLineManager != null) { + if (delta != null) { + fStatusLineManager.setMessage("\u0394: " + delta); //$NON-NLS-1$ + } else { + fStatusLineManager.setMessage(null); + } + } + } + // ------------------------------------------------------------------------ // Event cache // ------------------------------------------------------------------------ @@ -1895,9 +2169,6 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS // ISelectionProvider // ------------------------------------------------------------------------ - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ISelectionProvider#addSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) - */ /** * @since 2.0 */ @@ -1906,9 +2177,6 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS selectionChangedListeners.add(listener); } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ISelectionProvider#getSelection() - */ /** * @since 2.0 */ @@ -1917,7 +2185,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if (fTable == null || fTable.isDisposed()) { return StructuredSelection.EMPTY; } - List list = new ArrayList(fTable.getSelection().length); + List list = new ArrayList<>(fTable.getSelection().length); for (TableItem item : fTable.getSelection()) { if (item.getData() != null) { list.add(item.getData()); @@ -1926,9 +2194,6 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS return new StructuredSelection(list); } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ISelectionProvider#removeSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener) - */ /** * @since 2.0 */ @@ -1937,9 +2202,6 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS selectionChangedListeners.remove(listener); } - /* (non-Javadoc) - * @see org.eclipse.jface.viewers.ISelectionProvider#setSelection(org.eclipse.jface.viewers.ISelection) - */ /** * @since 2.0 */ @@ -2004,9 +2266,9 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS final IMarker bookmark = bookmarksFile.createMarker(IMarker.BOOKMARK); if (bookmark.exists()) { bookmark.setAttribute(IMarker.MESSAGE, message.toString()); - final long rank = (Long) tableItem.getData(Key.RANK); - final int location = (int) rank; - bookmark.setAttribute(IMarker.LOCATION, (Integer) location); + final Long rank = (Long) tableItem.getData(Key.RANK); + final int location = rank.intValue(); + bookmark.setAttribute(IMarker.LOCATION, Integer.valueOf(location)); fBookmarksMap.put(rank, bookmark.getId()); fTable.refresh(); } @@ -2026,26 +2288,28 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS * The bookmark to remove */ public void removeBookmark(final IMarker bookmark) { - for (final Entry entry : fBookmarksMap.entrySet()) { + for (final Entry entry : fBookmarksMap.entries()) { if (entry.getValue().equals(bookmark.getId())) { - fBookmarksMap.remove(entry.getKey()); + fBookmarksMap.remove(entry.getKey(), entry.getValue()); fTable.refresh(); return; } } } - private void toggleBookmark(final long rank) { + private void toggleBookmark(final Long rank) { if (fBookmarksFile == null) { return; } if (fBookmarksMap.containsKey(rank)) { - final Long markerId = fBookmarksMap.remove(rank); + final Collection markerIds = fBookmarksMap.removeAll(rank); fTable.refresh(); try { - final IMarker bookmark = fBookmarksFile.findMarker(markerId); - if (bookmark != null) { - bookmark.delete(); + for (long markerId : markerIds) { + final IMarker bookmark = fBookmarksFile.findMarker(markerId); + if (bookmark != null) { + bookmark.delete(); + } } } catch (final CoreException e) { displayException(e); @@ -2096,6 +2360,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } fSelectedRank = rank; fTable.setSelection(index + 1); // +1 for header row + updateStatusLine(null); } } @@ -2103,11 +2368,6 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS // Listeners // ------------------------------------------------------------------------ - /* - * (non-Javadoc) - * - * @see org.eclipse.linuxtools.tmf.ui.views.colors.IColorSettingsListener#colorSettingsChanged(org.eclipse.linuxtools.tmf.ui.views.colors.ColorSetting[]) - */ @Override public void colorSettingsChanged(final ColorSetting[] colorSettings) { fTable.refresh(); @@ -2138,6 +2398,7 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS if ((fPendingGotoRank != -1) && ((fPendingGotoRank + 1) < fTable.getItemCount())) { // +1 for header row fTable.setSelection((int) fPendingGotoRank + 1); // +1 for header row fPendingGotoRank = -1; + updateStatusLine(null); } } else { startFilterThread(); @@ -2163,9 +2424,10 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS // Create a request for one event that will be queued after other ongoing requests. When this request is completed // do the work to select the actual event with the timestamp specified in the signal. This procedure prevents // the method fTrace.getRank() from interfering and delaying ongoing requests. - final TmfDataRequest subRequest = new TmfDataRequest(ITmfEvent.class, 0, 1, ExecutionType.FOREGROUND) { + final TmfEventRequest subRequest = new TmfEventRequest(ITmfEvent.class, + TmfTimeRange.ETERNITY, 0, 1, ExecutionType.FOREGROUND) { - TmfTimestamp ts = new TmfTimestamp(signal.getCurrentTime()); + TmfTimestamp ts = new TmfTimestamp(signal.getBeginTime()); @Override public void handleData(final ITmfEvent event) { @@ -2211,12 +2473,13 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS } fTable.setSelection(index + 1); // +1 for header row fRawViewer.selectAndReveal(rank); + updateStatusLine(null); } }); } }; - ((ITmfDataProvider) fTrace).sendRequest(subRequest); + ((ITmfEventProvider) fTrace).sendRequest(subRequest); } } @@ -2244,4 +2507,33 @@ public class TmfEventsTable extends TmfComponent implements IGotoMarker, IColorS fTable.refresh(); fTable.redraw(); } + + /** + * Margin column for images and special text (e.g. collapse count) + */ + private static final class TmfMarginColumn extends TmfEventTableColumn { + + private static final @NonNull String HEADER = EMPTY_STRING; + + /** + * Constructor + */ + public TmfMarginColumn() { + super(HEADER); + } + + @Override + public String getItemString(ITmfEvent event) { + if (!(event instanceof CachedEvent) || ((CachedEvent) event).repeatCount == 0) { + return EMPTY_STRING; + } + return "+" + ((CachedEvent) event).repeatCount; //$NON-NLS-1$ + } + + @Override + public String getFilterFieldId() { + return null; + } + } + }